Okay thanks for your help; I changed my code with what you wrote, but I still have a more important leak. I also found that I have an indirect memory leak when decoding songs with a embedded album picture tag (which appears as Stream #0:1: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 160x160 [SAR 1:1 DAR 1:1], 90k tbr, 90k tbn, 90k tbc):
Indirect leak of 8686 byte(s) in 2 object(s) allocated from:
#0 0x7f7877199386 in __interceptor_posix_memalign /build/gcc-multilib/src/gcc-5.2.0/libsanitizer/asan/asan_malloc_linux.cc:105
    #1 0x7f78767c743f in av_malloc (/usr/lib/libavutil.so.54+0x2343f)

Maybe I should open another thread for this one? Now that we've seen that the leak does not come from the codec closing, do you have a clue where I could search?

The 29/08/2015 17:10, J Decker wrote :
On Sat, Aug 29, 2015 at 5:02 AM, Polochon Street <[email protected]> wrote:
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:
somethign more like...
          avpkt.data = NULL;
          avpkt.size = 0;
// just use your existing buffer here...
          decoded_frame = av_frame_alloc();
    do {
          avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
      } while (got_frame);
          av_frame_unref(decoded_frame);
          av_free_packet(&avpkt);

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 */


          avpkt.data = NULL;
          avpkt.size = 0;
// just use your existing buffer here...
          decoded_frame = av_frame_alloc();
    do {
          avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
      } while (got_frame);


      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
_______________________________________________
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