我有一个3500帧的HEVC序列,我正在写一个解码器来读取它(逐帧读取并转储到yuv)。 在我的main()中,我有一个for循环调用一个解码器()3500次(我假设在这个阶段main()知道有多少帧)。
因此,对于每次调用decoder(),我都需要返回一个完整的帧。 这就是解码器()的样子。
bool decode(pFormatCtx, pCodecCtx) { int gotaFrame=0; while (gotaFrame==0) { printf("1t"); if ( !av_read_frame(pFormatCtx, &packet) ) { if(packet.stream_index==videoStreamIndex) { // try decoding avcodec_decode_video2(pCodecCtx, pFrame, &gotaFrame, &packet); if (gotaFrame) { // decode success. printf("2t"); // dump to yuv ... not shown here. // cleanup av_frame_unref(pFrame); av_frame_free(&pFrame); av_free_packet(&packet); return true; } } } } }
行为是这样的:1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 1 2 ……看起来它在解码之前读取几帧? 第一帧是I帧,所以不应该立即解码?
使用此代码,我最终失去了几帧(由1系列表示)。 有人可以帮帮我吗? 我的代码中有什么问题吗?
更新:测试片段仅限video。 没有音频。
你所看到的是正确的行为。 解码器提供几帧以实现multithreading效率。 并且它可能需要几帧来“灌注泵”。 基本上,为了使您的程序保持响应,avcodec_decode_video2将帧排队等待解码,然后返回。 这可以防止您的程序长时间阻止。 在B帧的情况下也绝对需要延迟解码,其中解码顺序可能与显示顺序不同。
那么,如何不丢失这些帧? 在av_read_frame停止返回新帧之后,您必须通过使用空数据包调用avcodec_decode_video2来刷新解码器,直到不再重新调整帧为止。
最可能失败的是测试if(packet.stream_index==videoStreamIndex)
,而不是av_read_frame
:您可能正在读取来自另一个流的数据包(例如,音频流数据包被标记为“i-frames”)。
对于你的第一个I帧,I帧通常需要解码两个数据包(即第一次调用avcodec_decode_video2
返回gotaFrame == 0
)
需要了解更多c/c++开发分享如果我在FFmpeg中使用av_read_frame,则会丢失多个帧,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享如果我在FFmpeg中使用av_read_frame,则会丢失多个帧相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979228.html