Hello,
There is a memory leak in an application I am trying to build using the
libav* libraries. The application must read the decoded signal into a
buffer for each file in a directory. The perf monitor utility shows large
increases in both the number of private bytes and virtual bytes. It is the
same buffer for each file, so the increase is not strictly due to the signal
length.
These are the lib versions I am using.
Libavformat 52.23.1
Libavcodec 52.10.0
Libavutil 49.12.0
Libswscale 0.6.0
These are unofficial builds for the windows platform. I am building the
application in visual express c++ 2005 edition.
Here is the code I am using to read a signal into the input buffer. Keep in
mind, this is just for audio files. The function expects to be passed the
buffer in which to fill with the signal. If the sigbuf is too short or
NULL, it attempts to allocate a buffer for the signal. In either case, the
signal ptr is returned. Also, I have also included the stack trace dump
from umdh utility.
Any ideas as to what is causing this memory leak are greatly appreciated.
Thanks.
dgs.
__declspec(dllexport)
float* readaudio(const char *filename, int sr, int channels, float *sigbuf,
int &buflen)
{
int cap = 0;
av_register_all();
AVFormatContext *pFormatCtx;
// Open file
if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0){
buflen=0;
return NULL ; // Couldn't open file
}
// Retrieve stream information
if(av_find_stream_info(pFormatCtx)<0){
buflen=0;
return NULL; // Couldn't find stream information
}
//dump_format(pFormatCtx,0,NULL,0);//debugging function to print
infomation about format
unsigned int i;
AVCodecContext *pCodecCtx;
// Find the video stream
int audioStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
{
if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO)
{
audioStream=i;
break;
}
}
if(audioStream==-1){
buflen = 0;
return NULL; //no video stream
}
// Get a pointer to the codec context for the audio stream
pCodecCtx=pFormatCtx->streams[audioStream]->codec;
int64_t duration = pFormatCtx->streams[audioStream]->duration;
int src_sr = pCodecCtx->sample_rate;
int src_channels = pCodecCtx->channels;
float *buf;
if ((!sigbuf)&&(buflen < 0)){
buf = (float*)malloc(duration*sizeof(float)); /* alloc buffer */
buflen = (int)duration;
}
else
buf = sigbuf; /* use buffer handed in param */
AVCodec *pCodec;
// Find the decoder
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
buflen=0;
return NULL ; // Codec not found
}
// Open codec
if(avcodec_open(pCodecCtx, pCodec)<0){
buflen=0;
return NULL; // Could not open codec
}
uint8_t *in_buf = (uint8_t*)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE +
FF_INPUT_BUFFER_PADDING_SIZE);
int in_buf_used, numbytesread, buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
uint8_t *out_buf = (uint8_t*)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
int16_t *out_buf16 = (int16_t*)out_buf;
ReSampleContext *rs_ctx = audio_resample_init(channels, src_channels,
sr, src_sr);
int index = 0;
AVPacket packet;
while(av_read_frame(pFormatCtx, &packet)>=0)
{
in_buf_used = buf_size;
numbytesread =
avcodec_decode_audio2(pCodecCtx,(int16_t*)in_buf,&in_buf_used,packet.data,pa
cket.size);
if (numbytesread <= 0){
fprintf(stderr,"error reading from audiostream\n");
continue;
}
int cnt =
audio_resample(rs_ctx,(short*)out_buf,(short*)in_buf,(int)(in_buf_used/sizeo
f(int16_t)));
if (cap + cnt > buflen){
float *tmpbuf = (float*)realloc(buf,(buflen +
2*cnt)*sizeof(float));
if (!tmpbuf){
buflen=0;
return NULL;
}
buf = tmpbuf;
buflen += 2*cnt;
}
for (int i=0;i<cnt;i++){
buf[index+i] = ((float)out_buf16[i]/(float)SHRT_MAX);
}
cap += cnt;
index += cnt;
}
free(in_buf);
free(out_buf);
audio_resample_close(rs_ctx);
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
buflen = cap;
return buf;
}
Here is the offending stack trace that I found from umdh.exe dump.
(a compare file between two umdh logs).
// Debug library initialized ...
// + BYTES_DELTA (NEW_BYTES - OLD_BYTES) NEW_COUNT allocs BackTrace TRACEID
// + COUNT_DELTA (NEW_COUNT - OLD_COUNT) BackTrace TRACEID allocations
// BYTES_DELTA - increase in bytes between before and after log
// NEW_BYTES - bytes in after log
// OLD_BYTES - bytes in before log
// COUNT_DELTA - increase in allocations between before and after log
// NEW_COUNT - number of allocations in after log
// OLD_COUNT - number of allocations in before log
// TRACEID - decimal index of the stack trace in the trace database
// (can be used to search for allocation instances in the original
// UMDH logs).
//
+ 80519376 ( 116474520 - 35955144) 28271 allocs BackTrace234
+ 19544 ( 28271 - 8727) BackTrace234 allocations
ntdll!RtlDebugAllocateHeap+000000E1
ntdll!RtlAllocateHeapSlowly+00000044
ntdll!RtlAllocateHeap+00000E64
msvcrt!_heap_alloc+000000E0
msvcrt!_nh_malloc+00000013
msvcrt!malloc+00000027
avutil-49!av_malloc+00000025
Total increase == 80519376 requested + 469056 overhead = 80988432
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user