2

我正在尝试创建一个简单的媒体播放器来介绍 ffmpeg 的世界,问题是每次我调用av_freep(void*ptr)应用程序时都会崩溃。

如果我不调用av_freep我会出现内存泄漏并且程序使用的内存增加到 1000MB(已经测量),这里是代码:

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);

这是我的“DecodeAudioFrame”功能代码:

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;
}

我需要有关此问题的帮助,我不知道这是一个错误还是我需要做什么。那里发生了什么?为什么av_freep通话时会崩溃?我该如何解决?

谢谢

4

2 回答 2

4

av_freep获取指向要释放的指针的指针;它将释放的指针设置为NULL之后。因此,您需要将其用作

av_freep(&audioBuffer);

或者,您可以使用

av_free(audioBuffer);
audioBuffer = NULL;

这是等效的。

于 2013-05-11T15:40:19.970 回答
0
int16_t* audioBuffer=(int16_t*)av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE+FF_INPUT_BUFFER_PADDING_SIZE);

这是错误的。AVCODEC_MAX_AUDIO_FRAME_SIZE已弃用(在新版本中已删除)。使用新的解码 API,您可以获得比这更大的解码帧。

static AVFrame frame;

不。不要在堆栈上分配 AVFrame,它会中断。使用avcodec_alloc_frame()(或av_frame_alloc()与新版本一起使用)。

data_size = av_samples_get_buffer_size(frame.linesize,channel_count,sample_fr,_audio_ccontext->sample_fmt,1);

你意识到你覆盖了原来的框架线尺寸(也就是平面尺寸),对吧?我想知道这是不是故意的。

还有,什么是sample_fr?那是某个地方的常数吗?只需使用 AVFrame.nb_samples。

最后,您的代码显然假设交错音频(即,在一个缓冲区中交错的所有通道的音频样本)。许多解码器现在输出平面音频(即每个通道的样本在单独的缓冲区中)。这可能是崩溃的原因,因为av_samples_get_buffer_size计算所有通道中所有样本的总大小,而data[0]仅包含第一个通道的样本。

如果平面音频确实是原因,您应该修改代码以支持它,或者使用libavresample将平面转换为交错

于 2013-05-12T10:21:46.660 回答