• 关于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 随着时间轴的推移,真正编码出来然后送去打包的顺序是这样的

     5 DTS 是编码时间戳,PTS是从摄像头拿出来的时间戳,实际你编码后,就是按照下图顺序输出并送给封装库的;YUV数据是按照顺序送给编码器的,你中间插入的B帧越多,那编码器缓冲就越多大,因为它要跳帧先去编码后边的YUV,中间用来编码B帧的YUV要存起来呀;

     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头来了的时候你也要触发一下解码器内部缓冲重排序;

     

  • 相关阅读:
    css3 容器内容垂直居中
    css3 背景图动画一
    C# linq 最大、最小对象的扩展
    线程中为控件赋值Winform
    C#在高分屏上让窗体程序忽略系统的显示缩放
    获取搜索到的内容
    XMLHelper
    获得WebBrowser中的图片数据
    单例模式通用类
    将实体类、匿名对象转换为SqlParameter列表
  • 原文地址:https://www.cnblogs.com/8335IT/p/16299003.html
Copyright © 2020-2023  润新知