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

有帮助吗?

解决方案

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.

其他提示

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top