[Libav-user] Closing codec properly after an audio decoding
Polochon Street
polochonstreet at gmx.fr
Thu Aug 27 22:21:57 CEST 2015
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;
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20150827/0c00df2d/attachment.html>
More information about the Libav-user
mailing list