关于B帧解码顺序的讨论
1 摄像头采集出来的YUV的顺序是PTS显示的顺序,打的时间戳是PTS,显示时间戳
2现在我告诉编码器,你要给我编码一些B帧,那就会出现跳跃性编码
“ 仅仅使用前一个显示的基准帧来编码的帧被称为“P帧”,同时使用前一个显示帧和未来帧作为基准帧进行编码的帧称为“B帧;从压缩的程度来看,I画面的压缩量最少;P画面次之,它是以I画面为基础;B画面压缩最多。为了加大压缩比,通常在I帧后面相隔2帧(最多3帧)设置1个P帧,在I、P帧之间都是B帧,在两个P帧之间也是设置2~3帧B帧。B帧传送它与I帧或P帧之间的差值信息,或者P帧与后面P帧或I帧之间的差值信息,或者它与前后I、P帧或P、P帧平均值之间的差值信息。当主体内容变化愈大时,两个I画面之间的帧数值越小;当主体内容变化小时,I面画的间隔可以适当大一些”
原文链接:https://blog.csdn.net/ssllkkyyaa/article/details/110138393
3 编码器一般将“画面场景切换”OR“首个画面” 编码成I帧;将一些场景变换略大,但又不足以需要编码新的I帧的YUV的编码成P帧;而一些I帧向P帧过渡的画面编码成B帧;pts是显示时间戳,也就是从摄像头出来的顺序;既渲染的顺序;
4 随着时间轴的推移,真正编码出来然后送去打包的顺序是这样的

6 经过网络传输和解析,你解析后的数据就是这个样子(一般解析后的数据的顺序按照PTS的顺序来看)
6你把这个送去解码,解码器按顺序解码 I,P,B,B,送去渲染播放;但是pts =2,pts=3的两个B帧应该在P帧前边播放,我们不应该按照DTS的顺序播放,而是应该按照PTS正序去播放;
那这里就需要有一个解码后的缓冲区,当码流是有B帧的,你要等B帧和它需要参考的帧都解码完再去做个排序,然后再输出解码器;索性你会发现,其实在你解码B帧的时候,他需要参考的帧其实已经解码完了;就比如这里的pts =2 和Pts=3 的两帧,这两个B帧需要参考的首尾帧I(pts=1)和P(pts = 4);都已经优先送给解码器了;
7 那我们什么时候知道I和P之间的B解码完了,我可以去做排序了,呢?不知道你有没有发现,解析后的B帧是夹在两个P帧之间的?
所以是不是可以当你解码的时候,如果送来了第二个P帧(pts=7),触发一下缓冲排序(排 pts= 4,2,3的三帧),然后输出解码器,(将P个数标志位重置回1,等待下一个P来的时候在触发下一次的逆置);B帧是不可能参考后边的IDR的,因为一般I帧是一个新的场景,B帧不可能既参考前边一个场景的P,还有参考后一个场景的I;
那假设这里没有Pts= 8的这帧;我怎么把一个GOP的最后一个需要排序的小序列触发排序呢,这里我觉得Pts= 8如果不是P,那就应该是I,那就相当于新的GOP头来了的时候你也要触发一下解码器内部缓冲重排序;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2020-05-22 Mac的音频midi设置
2018-05-22 画面撕裂
2018-05-22 倍频插帧