Reputation: 1391
I am trying to create a simple media-player for an introduction to the world of ffmpeg, the problem is that every time that I call av_freep(void*ptr)
the application crashes.
If I don't call av_freep
I get a memory leak and the memory used by the program increases up to 1000MB (Already measured), here is the code:
int16_t* audioBuffer=(int16_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE+FF_INPUT_BUFFER_PADDING_SIZE);
if(!audioBuffer){
MessageBox(0,"Error allocating in audioBuffer","Error: Mem",MB_ICONWARNING | MB_OK);
return -1;
}
int sz = MEDIA->DecodeAudioFrame((void*)audioBuffer,0);
Pa_WriteStream(MEDIA->output_stream,(int16_t*)audioBuffer,MEDIA->_audio_ccontext->frame_size);
av_freep(audioBuffer);
Here is my 'DecodeAudioFrame' function code:
int WbMedia::DecodeAudioFrame(void *audio_buf, int buf_size){
static AVFrame frame;
static AVPacket pkt;
static uint8_t *audio_pkt_data = NULL;
static int audio_pkt_size = 0;
int len1=0;
for(;;){
bool do_rt = false;
while(audio_pkt_size > 0){
int obt_frame = 0;
len1 = avcodec_decode_audio4(_audio_ccontext,&frame,&obt_frame,&pkt);
if(len1 < 0){
audio_pkt_size = 0;
break;
}
audio_pkt_data+=len1;
audio_pkt_size-=len1;
if(obt_frame){
data_size = av_samples_get_buffer_size(frame.linesize,channel_count,sample_fr,_audio_ccontext->sample_fmt,1);
memcpy(audio_buf,frame.data[0],data_size);
}
if(data_size < 0){
continue;
}
if(pkt.data){
av_free_packet(&pkt);
}
return data_size;
}
if(pkt.data){
av_free_packet(&pkt);
}
if(do_rt){
return data_size;
}
// Try to get a new packet
if(!audio_packets.empty()){
WaitForSingleObject(Queue_Audio_Mutex,INFINITE);
pkt = audio_packets.front();
audio_packets.pop();
ReleaseMutex(Queue_Audio_Mutex);
audio_pkt_size = pkt.size;
audio_pkt_data = pkt.data;
}else{
return -1;
}
}
return 0;
}
I need help with this issue, I don't know if it is a bug or what I need to do. What's happening there? Why does it crashes on the av_freep
call? How can I fix it?
Thanks
Upvotes: 2
Views: 2651
Reputation: 813
int16_t* audioBuffer=(int16_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE+FF_INPUT_BUFFER_PADDING_SIZE);
This is wrong. AVCODEC_MAX_AUDIO_FRAME_SIZE
is deprecated (removed in new versions). With the new decoding API you can get larger decoded frames than this.
static AVFrame frame;
No. Do not allocate AVFrame on stack, it will break. Use avcodec_alloc_frame()
(or av_frame_alloc()
with new versions).
data_size = av_samples_get_buffer_size(frame.linesize,channel_count,sample_fr,_audio_ccontext->sample_fmt,1);
You realize you're oveerwriting the original frame linesize (AKA the plane size), right? I wonder if that is intended.
Also, what is sample_fr
? Is that some constant from somewhere? Just use AVFrame.nb_samples.
Finally, your code apparrently assumes interleaved audio (i.e. the audio samples for all the channels interleaved in one buffer). Many decoders now output planar audio (i.e. the samples for each channel in a separate buffer). This might be the reason for the crash, since av_samples_get_buffer_size
calculates the total size for all the samples in all channels, while data[0]
will contain only the samples for the first channel.
If planar audio is indeed the reason, you should either modify your code to support it, or use libavresample to convert planar to interleaved
Upvotes: 0
Reputation: 179442
av_freep
takes a pointer to the pointer you want to free; it sets the freed pointer to NULL
afterwards. Therefore, you need to use it as
av_freep(&audioBuffer);
Alternatively, you can use
av_free(audioBuffer);
audioBuffer = NULL;
which is equivalent.
Upvotes: 4