gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 02:43:28 24 4
gpt4 key购买 nike

我正在使用 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); (免费 1)av_free_packet(&packet); (免费 2 个)。结果是应用程序崩溃并显示消息 “Heap Corruption...”

如果我不释放数据包,就会发生内存泄漏。

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

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

非常感谢,

大同

最佳答案

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

几个建议:

  • 如果您的数据包的第一次使用是 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
}

关于c++ - FFMPEG:解码 H264 流时无法释放 AVPacket?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26090992/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com