So, what should I do? Set avpkt.data to NULL and avpkt.size to 0, and then close the codec?
I tried to add at the end of the loop:
  do {
        avpkt.data = NULL;
        avpkt.size = 0;
        decoded_frame = av_frame_alloc();
        avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
        av_frame_unref(decoded_frame);
        av_free_packet(&avpkt);
    } while (got_frame);

But now I'm leaking more memory...

The 29/08/2015 13:10, J Decker wrote :
You didn't pass a null packet to flush the codec at the end and get
the remaining packets from the stream.

On Thu, Aug 27, 2015 at 1:21 PM, Polochon Street <[email protected]> wrote:
Hi!
I use the following code (see below) in order to decode an audio file into
an array, and I'm having a memory leak of 24kb:
Direct leak of 24 byte(s) in 1 object(s) allocated from:
     #0 0x7f80c449e386 in __interceptor_posix_memalign
/build/gcc-multilib/src/gcc-5.2.0/libsanitizer/asan/asan_malloc_linux.cc:105
     #1 0x7f80c3acc43f in av_malloc (/usr/lib/libavutil.so.54+0x2343f)

So I'm thinking that it's due to some libav-specific things that I didn't
close properly, and so here's my question: is avcodec_close(context);
sufficient to free a codec context and a codec? This example
(http://ffmpeg.org/doxygen/trunk/decoding_encoding_8c-example.html) does an
av_free(context), but my program crashes when I try to do it...

Thanks by advance!
Polochon_street

#define INBUF_SIZE 4096

#define AUDIO_INBUF_SIZE 20480

#define AUDIO_REFILL_THRESH 4096


#include "analyze.h"


int audio_decode(const char *filename, struct song *song) { // decode the
track

     AVCodec *codec = NULL;

     AVCodecContext *c = NULL;

     AVFormatContext *pFormatCtx;



     int i, d, e;

     int len;

     int planar;

     AVPacket avpkt;

     AVFrame *decoded_frame = NULL;

     int8_t *beginning;

     int got_frame;

     int audioStream;

     size_t index;


     av_register_all();

     av_init_packet(&avpkt);


     pFormatCtx = avformat_alloc_context();


     if(avformat_open_input(&pFormatCtx, filename, NULL, NULL) < 0) {

         printf("Couldn't open file: %s, %d\n", filename, errno);

         song->nSamples = 0;

         return 1;

     }


     if(avformat_find_stream_info(pFormatCtx, NULL) < 0) {

         printf("Couldn't find stream information\n");

         song->nSamples = 0;

         return 1;

     }


     audioStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_AUDIO, -1,
-1, &codec, 0);

     c = pFormatCtx->streams[audioStream]->codec;



     if (!codec) {

         printf("Codec not found!\n");

         song->nSamples = 0;

         return 1;

     }


     if(avcodec_open2(c, codec, NULL) < 0) {

         printf("Could not open codec\n");

         song->nSamples = 0;

         return 1;

     }



     song->sample_rate = c->sample_rate;

     song->duration = pFormatCtx->duration/AV_TIME_BASE;

     size =
(((uint64_t)(pFormatCtx->duration)*(uint64_t)song->sample_rate)/(uint64_t)AV_TIME_BASE)*c->channels*av_get_bytes_per_sample(c->sample_fmt);

     song->nSamples =
(((uint64_t)(pFormatCtx->duration)*(uint64_t)song->sample_rate)/(uint64_t)AV_TIME_BASE)*c->channels;

     song->sample_array = malloc(size);


     for(i = 0; i < size; ++i)

         song->sample_array[i] = 0;


     beginning = song->sample_array;

     index = 0;


     planar = av_sample_fmt_is_planar(c->sample_fmt);

     song->nb_bytes_per_sample = av_get_bytes_per_sample(c->sample_fmt);


     song->channels = c->channels;



/* End of codec init */

     while(av_read_frame(pFormatCtx, &avpkt) >= 0) {

         if(avpkt.stream_index == audioStream) {

             got_frame = 0;



             if(!decoded_frame) {

                 if(!(decoded_frame = av_frame_alloc())) {

                     printf("Could not allocate audio frame\n");

                     exit(1);

                 }

             }

             else

                 av_frame_unref(decoded_frame);


             len = avcodec_decode_audio4(c, decoded_frame, &got_frame,
&avpkt);



             if(len < 0)

                 avpkt.size = 0;


             av_free_packet(&avpkt);


             /* interesting part: copying decoded data into a huge array */

             /* flac has a different behaviour from mp3, hence the planar
condition */

             if(got_frame) {

                 size_t data_size = av_samples_get_buffer_size(NULL,
c->channels, decoded_frame->nb_samples, c->sample_fmt, 1);


                 if(index*song->nb_bytes_per_sample + data_size > size) {

                     beginning = realloc(beginning, (size += data_size));

                     song->nSamples += data_size/song->nb_bytes_per_sample;

                 }

                 int8_t *p = beginning+index*song->nb_bytes_per_sample;

                 if(planar == 1) {

                     for(i = 0; i <
decoded_frame->nb_samples*song->nb_bytes_per_sample; i +=
song->nb_bytes_per_sample) {

                         for(e = 0; e < c->channels; ++e)

                             for(d = 0; d < song->nb_bytes_per_sample; ++d)

                                 *(p++) =
((int8_t*)(decoded_frame->extended_data[e]))[i+d];

                     }

                     index += data_size/song->nb_bytes_per_sample;

                 }

                 else if(planar == 0) {

                     memcpy(index*song->nb_bytes_per_sample + beginning,
decoded_frame->extended_data[0], data_size);

                     index += data_size/song->nb_bytes_per_sample;

                 }

             }

         }

     }

     song->sample_array = beginning;


     /* cleaning memory */



     avcodec_close(c);

     av_frame_unref(decoded_frame);

     av_frame_free(&decoded_frame);

     av_free_packet(&avpkt);

     avformat_close_input(&pFormatCtx);


     return 0;

}


_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to