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

时间:2014-09-29 00:28:09

标签: c++ ffmpeg decode h.264

我正在使用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 2)两个地点之一来删除数据包的数据。结果是应用程序崩溃了消息"Heap Corruption..."

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

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

时崩溃

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

非常感谢,

T&amp; T公司

2 个答案:

答案 0 :(得分:2)

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

几个建议:

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

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

  • 一旦你的打包被解码(即avcodec_decode_video2没问题,无论frameFinished是真还是假),你都可以释放它。无需保留它并更改数据指针。该过程是&#34;读取数据包,解码,释放它。读取下一个数据包,解码,释放它。&#34;。 (请注意,这不适用于音频数据包)。

我建议通过类似的方式简化主循环(首先读取,然后解码):

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
}

答案 1 :(得分:1)

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

AVPacket        packet;
av_init_packet(&packet);

您也不要删除AVFormatContext个实例。

avformat_free_context(pFormatCtx);
相关问题