<html>
  <head>

    <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hi!<br>
    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:<br>
    Direct leak of 24 byte(s) in 1 object(s) allocated from:<br>
        #0 0x7f80c449e386 in __interceptor_posix_memalign
/build/gcc-multilib/src/gcc-5.2.0/libsanitizer/asan/asan_malloc_linux.cc:105<br>
        #1 0x7f80c3acc43f in av_malloc
    (/usr/lib/libavutil.so.54+0x2343f)<br>
    <br>
    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 <b>and</b>
    a codec? This example
    (<a class="moz-txt-link-freetext" href="http://ffmpeg.org/doxygen/trunk/decoding_encoding_8c-example.html">http://ffmpeg.org/doxygen/trunk/decoding_encoding_8c-example.html</a>)
    does an av_free(context), but my program crashes when I try to do
    it...<br>
    <br>
    Thanks by advance!<br>
    Polochon_street<br>
    <br>
    <p>#define INBUF_SIZE 4096<br>
      <br>
    </p>
    <p>#define AUDIO_INBUF_SIZE 20480</p>
    <p>#define AUDIO_REFILL_THRESH 4096</p>
    <p><br>
      #include "analyze.h"</p>
    <p><br>
      int audio_decode(const char *filename, struct song *song) { //
      decode the track</p>
    <p>    AVCodec *codec = NULL;</p>
    <p>    AVCodecContext *c = NULL;</p>
    <p>    AVFormatContext *pFormatCtx;</p>
    <p>    </p>
    <p>    int i, d, e;</p>
    <p>    int len;</p>
    <p>    int planar;</p>
    <p>    AVPacket avpkt;</p>
    <p>    AVFrame *decoded_frame = NULL;</p>
    <p>    int8_t *beginning;</p>
    <p>    int got_frame;</p>
    <p>    int audioStream;</p>
    <p>    size_t index;</p>
    <p><br>
          av_register_all();</p>
    <p>    av_init_packet(&avpkt);</p>
    <p><br>
          pFormatCtx = avformat_alloc_context();</p>
    <p><br>
          if(avformat_open_input(&pFormatCtx, filename, NULL, NULL)
      < 0) {</p>
    <p>        printf("Couldn't open file: %s, %d\n", filename, errno);</p>
    <p>        song->nSamples = 0;</p>
    <p>        return 1;</p>
    <p>    }</p>
    <p><br>
          if(avformat_find_stream_info(pFormatCtx, NULL) < 0) {</p>
    <p>        printf("Couldn't find stream information\n");</p>
    <p>        song->nSamples = 0;</p>
    <p>        return 1;</p>
    <p>    } </p>
    <p><br>
          audioStream = av_find_best_stream(pFormatCtx,
      AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);</p>
    <p>    c = pFormatCtx->streams[audioStream]->codec;</p>
    <p>    </p>
    <p>    if (!codec) {</p>
    <p>        printf("Codec not found!\n");</p>
    <p>        song->nSamples = 0;</p>
    <p>        return 1;</p>
    <p>    }</p>
    <p><br>
          if(avcodec_open2(c, codec, NULL) < 0) {</p>
    <p>        printf("Could not open codec\n");</p>
    <p>        song->nSamples = 0;</p>
    <p>        return 1;</p>
    <p>    }</p>
    <p>    </p>
    <p>    song->sample_rate = c->sample_rate;</p>
    <p>    song->duration = pFormatCtx->duration/AV_TIME_BASE;</p>
    <p>    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);</p>
    <p>    song->nSamples =
(((uint64_t)(pFormatCtx->duration)*(uint64_t)song->sample_rate)/(uint64_t)AV_TIME_BASE)*c->channels;</p>
    <p>    song->sample_array = malloc(size);</p>
    <p><br>
          for(i = 0; i < size; ++i)</p>
    <p>        song->sample_array[i] = 0;</p>
    <p><br>
          beginning = song->sample_array;</p>
    <p>    index = 0;</p>
    <p><br>
          planar = av_sample_fmt_is_planar(c->sample_fmt);</p>
    <p>    song->nb_bytes_per_sample =
      av_get_bytes_per_sample(c->sample_fmt);</p>
    <p><br>
          song->channels = c->channels;</p>
    <p>    </p>
    <p>/* End of codec init */</p>
    <p>    while(av_read_frame(pFormatCtx, &avpkt) >= 0) {</p>
    <p>        if(avpkt.stream_index == audioStream) {</p>
    <p>            got_frame = 0; </p>
    <p>        </p>
    <p>            if(!decoded_frame) {</p>
    <p>                if(!(decoded_frame = av_frame_alloc())) {</p>
    <p>                    printf("Could not allocate audio frame\n");</p>
    <p>                    exit(1);</p>
    <p>                }</p>
    <p>            }</p>
    <p>            else </p>
    <p>                av_frame_unref(decoded_frame);</p>
    <p><br>
                  len = avcodec_decode_audio4(c, decoded_frame,
      &got_frame, &avpkt);</p>
    <p>    </p>
    <p>            if(len < 0)</p>
    <p>                avpkt.size = 0;</p>
    <p><br>
                  av_free_packet(&avpkt);</p>
    <p><br>
                  /* interesting part: copying decoded data into a huge
      array */</p>
    <p>            /* flac has a different behaviour from mp3, hence the
      planar condition */</p>
    <p>            if(got_frame) {</p>
    <p>                size_t data_size =
      av_samples_get_buffer_size(NULL, c->channels,
      decoded_frame->nb_samples, c->sample_fmt, 1); </p>
    <p><br>
                      if(index*song->nb_bytes_per_sample + data_size
      > size) {</p>
    <p>                    beginning = realloc(beginning, (size +=
      data_size));</p>
    <p>                    song->nSamples +=
      data_size/song->nb_bytes_per_sample;</p>
    <p>                }</p>
    <p>                int8_t *p =
      beginning+index*song->nb_bytes_per_sample;</p>
    <p>                if(planar == 1) {</p>
    <p>                    for(i = 0; i <
      decoded_frame->nb_samples*song->nb_bytes_per_sample; i +=
      song->nb_bytes_per_sample) { </p>
    <p>                        for(e = 0; e < c->channels; ++e)</p>
    <p>                            for(d = 0; d <
      song->nb_bytes_per_sample; ++d) </p>
    <p>                                *(p++) =
      ((int8_t*)(decoded_frame->extended_data[e]))[i+d];</p>
    <p>                    }</p>
    <p>                    index +=
      data_size/song->nb_bytes_per_sample;</p>
    <p>                }</p>
    <p>                else if(planar == 0) {</p>
    <p>                    memcpy(index*song->nb_bytes_per_sample +
      beginning, decoded_frame->extended_data[0], data_size);</p>
    <p>                    index +=
      data_size/song->nb_bytes_per_sample; </p>
    <p>                }</p>
    <p>            }</p>
    <p>        }</p>
    <p>    }</p>
    <p>    song->sample_array = beginning;</p>
    <p><br>
          /* cleaning memory */</p>
    <p>    </p>
    <p>    avcodec_close(c);</p>
    <p>    av_frame_unref(decoded_frame);</p>
    <p>    av_frame_free(&decoded_frame);</p>
    <p>    av_free_packet(&avpkt);</p>
    <p>    avformat_close_input(&pFormatCtx);</p>
    <p><br>
          return 0;</p>
    <p>}<br>
    </p>
  </body>
</html>