关于ffmpeg解码含有B帧的H264流时的疑惑

xiao17174 2014-01-13 08:12:57
按照我从网上查的资料,解码器会重新排序含有B帧的H264数据流:
the Input sequence for video decoder
1 4 2 3 7 5 6
I P B B I B B

Let's take 1,2,3.. as PTS for simplification

the out sequence for video decoder
1 2 3 4 5 6 7
I B B P B B I


但是问题是,ffmpeg在解码时,每一帧解码时调用avcodec_decode_video2(),要么得到YUV,要么没得到.
那么,假设我按照上面的帧队列来调用avcodec_decode_video2(),第一次input[0]是I帧肯定解码成功并得到图像,可第二次当我开始解码input[1]也就是PTS为4的P帧时,avcodec_decode_video2()会返回什么?如果它返回成功并得到图像,那网上的说法就不对了.因为它先于PTS为2的B帧的图像返回了.也就是说ffmpeg没有帮我重新排序.经过我验证这是不会发生的,更有可能是下面这样:
它返回的是解码成功,但是没有得到图像失败,那就是说ffmpeg把P帧保存到缓存了,那问题就来了,如果我一共有4帧视频分别为I,B,B,P,编码后顺序:IPBB.我调了四次接口,第一次得到了一张图像,第二次没有得到.第三次得到了.第四次也得到了.也就是说我一共才得到3张图像?如果ffmpeg真的是这样工作的,那我是不是丢失了一帧图像?那缓存里的图像我怎么样才能得到?
...全文
1045 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
realzjie1 2014-10-30
  • 打赏
  • 举报
回复
结束时不用循环调用avcodec_decode_video2,最后缓冲的帧数应该就只有一帧(P帧)
xiao17174 2014-01-15
  • 打赏
  • 举报
回复
值得一提的是丢失的也就是缓存的帧数不会很大,一般1-5帧左右.这个数值是固定的并且由最大B帧决定的. 另外,可以检测ffmpeg解码器的capabilities,如果具备CODEC_CAP_DELAY.那么应该(或者是必须)在解码完所有帧后,继续循环调用解码接口,同时把输入包AVPacket的数据指针置为NULL,大小置为0.直到返回got_pictrue为0为止.这样才能保证得到与输入帧对应数量的所有的图像.
xiao17174 2014-01-15
  • 打赏
  • 举报
回复
引用 3 楼 dream238 的回复:
参考这个文章试试:http://blog.yikuyiku.com/?tag=avcodec_decode_video2
感谢你的回复,这个链接的文章确实证实了我的猜测.即涉及到双向预测的B帧时,ffmpeg会缓存后向的引用帧.所以最后如果在认为input完所有的未解码帧后就关闭解码器会导致丢失部分帧. 结帖!
ArcRain 2014-01-15
  • 打赏
  • 举报
回复
xiao17174 2014-01-14
  • 打赏
  • 举报
回复
引用 1 楼 u010806377 的回复:
不是,因为有个缓存,继续参考解码。交流Q:1049568282
是的,我知道,他缓存了P帧,直到没有B帧依赖于它的时候,再把它交出来给我.但问题是,我每次调解码接口时,我只期望或者说只接收一帧图像的YUV.也就是说我有四帧,我调了四次解码,我只期望我接收4幅图像.但是因为其中有一次我调解码它没有返回图像,也就说是我实际上只接收到了3幅图像,还有一帧P帧它还缓存着.但这时候我认为我已经把所有的帧解码完了.我就去关闭解码器了啊.这样我不就丢失了一帧图像吗?难道我最后要用一个空包去调一次avcodec_decode_video2()吗?这样它就会把缓存的帧都给我?

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧