繁体   English   中英

FFMPEG:解码H264流时无法释放AVPacket?

[英]FFMPEG: Can not free AVPacket when decode H264 stream?

我正在使用FFMPEG来解码H264流,我的代码如下

AVFormatContext *pFormatCtx = NULL;
AVCodecContext  *pCodecCtx = NULL;
AVFrame         *pFrame = NULL;
AVPacket        packet;
packet.data = NULL;

pFormatCtx = avformat_alloc_context();  
avformat_open_input(&pFormatCtx, videoStreamPath, NULL, NULL);
liveHeader.pCodecCtx = pFormatCtx->streams[videoStreamIndex]->codec;

int  bytesDecoded = 0;
int  frameFinished = 0;
while (true)
{
    while (packet.size > 0)
    {
        // Decode the next chunk of data
        bytesDecoded = avcodec_decode_video2(pCodecCtx, pFrame,
            &frameFinished, &packet);

        // Was there an error?
        if (bytesDecoded < 0)
        {
            printf(strErr, "Error while decoding frame\n");
            commonGlobal->WriteRuntimeRecLogs(strErr);
            return RS_NOT_OK;
        }

        packet.size -= bytesDecoded;
        packet.data += bytesDecoded;
        if (frameFinished)
        {               
            //av_free_packet(&packet); //(free 1)
            return RS_OK;
        }
        // Did we finish the current frame? Then we can return
    }
    do
    {
        try
        {
            int ret = av_read_frame(pFormatCtx, &packet);
            if (ret < 0)
            {
                char strErr[STR_LENGTH_256];
                if (ret == AVERROR_EOF || (pFormatCtx->pb && pFormatCtx->pb->eof_reached))
                {
                    sprintf(strErr, "Error end of file line %d", __LINE__);
                }
                if (pFormatCtx->pb && pFormatCtx->pb->error)
                {
                    sprintf(strErr, "Error end of file line %d", __LINE__);
                }
                packet.data = NULL;
                return RS_NOT_OK;
            }
        }
        catch (...)
        {
            packet.data = NULL;
            return RS_NOT_OK;
        }
    } while (packet.stream_index != videoStreamIndex);
}

//av_free_packet(&packet); //(free 2)

问题是我不知道如何正确释放packet内存。

我试图通过调用两个地方中的一个来删除数据包的数据av_free_packet(&packet); (free 1) av_free_packet(&packet); (free 1)av_free_packet(&packet); (free 2) av_free_packet(&packet); (free 2) 结果是应用程序崩溃了"Heap Corruption..."这个消息"Heap Corruption..."

如果我不释放packet ,则会发生内存泄漏。

注意上面的代码在解码H264流时成功,主要问题是内存泄漏并在我尝试释放packet时崩溃

有人可以告诉我代码中的问题。

非常感谢,

T&T

av_free_packet将清除您的数据包数据,这是在av_read_frame内分配的相同指针。 但你在packet.data += bytesDecoded;更改了它packet.data += bytesDecoded; =>崩溃。

几个建议:

  • 如果首次使用您的数据包是av_read_frame ,则无需调用av_init_packet (在此函数内部完成)。 但是如果你保留你的代码,你需要它来将packet.size初始化为0(测试,但第一次没有初始化)

  • 每次完成数据包数据时,只有在解码成功时才调用av_free_packet 在您的代码中,这意味着您必须在avcodec_decode_video2之后调用它,即使帧未完成。

  • 一旦你的包装被解码(即avcodec_decode_video2是确定的,不管frameFinished是真的还是假的),你可以释放它。 无需保留它并更改数据指针。 这个过程是“读取数据包,解码它,释放它。读取下一个数据包,解码它,释放它。”。 (请注意,这不适用于音频数据包)。

我建议通过类似的东西来简化你的主循环(先读取,然后解码):

while(true)
{
    // Step 1: Read packet
    while(true)
    {
        av_read_frame(pFormatCtx, &packet);

        // todo: Error handling

        if(packet.stream_index != videoStreamIndex)
        {
            av_free_packet(&packet);
        }
        else
        {
            break;
        }
    } while (packet.stream_index != videoStreamIndex);

    // Step 2/3: Decode and free
    avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
    av_free_packet(&packet);

    // todo: Error handling and checking frameFinished if needed
    // Of course, if you need to use the packet now, move the av_free_packet() after this
}

您应该在使用前初始化数据包,如下所示:

AVPacket        packet;
av_init_packet(&packet);

您也不要删除AVFormatContext实例。

avformat_free_context(pFormatCtx);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM