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

Reply via email to