1)什么是I帧、P帧、B帧?
2)什么是IDR帧?与普通I帧有何区别?
3)什么是GOP?gop_size值如何设置画质会更好?
4)OpenGOP & CloseGOP表示什么?
5)视频流中的PTS和DTS又是什么?
什么是I帧、P帧、B帧?
I帧:intra picture,帧内编码帧。I帧通常是每个GOP的第一个帧,可以看作一个图像经过压缩后的产物,如上期所提到的HEIF图像压缩编码,实际就可理解为H.265/HEVC标准下视频编码过程中一个序列中的I帧。解码时只需要本帧数据就可以完成(因为包含完整画面 ),一个GOP中,I帧作为编解码的起点,能有效防止帧间预测误差累计扩散。
- I帧自身可以通过视频解压算法解压成一张单独的完整视频画面,所以I帧去掉的是视频帧在空间维度上的冗余信息。
I帧特点:
1)I帧是一个全帧压缩编码帧;
2)解码时仅用I帧的数据就可重构完整图像;
3)I帧描述了图像背景和运动主体的详情;
4)I帧不需要参考其他画面而生成;
5)I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各帧的质量);
6)I帧是帧组GOP的基础帧(第一帧),在一组GOP中只有一个I帧;
7)I帧不需要考虑运动矢量;
8)I帧所占数据的信息量比较大。
P帧:predictive-frame,前向预测编码帧。通过将图像序列中前面已编码帧的时间冗余信息充分去除来压缩传输数据量的编码图像,也称为预测帧。P帧表示的是这一帧跟之前的帧的差别,P帧可以作为后续图像编码时的参考帧。解码时需要用之前缓存的画面叠加上本帧定义的差别,生成最终画面。(也就是差别帧,P帧没有完整画面数据,只有与前一帧的画面差别的数据,因此解码要使用参考图像的像素值。)
- P帧需要参考其前面的一个I帧或者P帧来解码成一张完整的视频画面。
P帧特点:
1)P帧采用运动补偿的方法传送它与前面的I或P帧的差值及运动矢量(预测误差);
2)解码时必须将I帧中的预测值与预测误差求和后才能重构完整的P帧图像;
3)P帧属于前向预测的帧间编码,它只参考前面最靠近它的I帧或P帧;
4)P帧可以是其后面P帧的参考帧,也可以是其前后的B帧的参考帧;
5)由于是差值传送,P帧的压缩比较高。
B帧:bi-directional interpolated prediction frame,双向预测内插编码帧。既考虑源图像序列前面的已编码帧,又顾及源图像序列后面的已编码帧之间的时间冗余信息,来压缩传输数据量的编码图像,也称为双向预测帧。要解码B帧,不仅要取得之前的缓存画面,还要解码之后的画面,通过前后画面的与本帧数据的叠加取得最终的画面。
- B帧需要参考其前一个I帧或者P帧及其后面的一个P帧来生成一张完整的视频画面,P帧与B帧去掉的是视频帧在时间维度上的冗余信息。
B帧特点:
1)B帧是由前面的I或P帧和后面的P帧来进行预测的;
2)B帧传送的是它与前面的I或P帧和后面的P帧之间的预测误差及运动矢量;
3)B帧是双向预测编码帧;
4)B帧压缩比最高,因为它只反映参考帧间运动主体的变化情况,预测比较准确;
5)B帧不是参考帧,不会造成解码错误的扩散。
什么是IDR帧?与普通I帧有何区别?
IDR(instantaneous decoding refresh picture),即时解码刷新帧,一个序列的第一帧便是IDR帧。IDR帧也是I帧的一种,那么IDR帧与普通I帧有何区别呢?
一个IDR帧之后的所有帧都不能引用该 IDR 帧之前的帧的内容;而对于普通的I帧,其后的P帧和B帧可以引用该普通I帧之前的其他I帧。IDR帧的作用是立刻刷新,使错误不致传播,从IDR帧开始,重新算一个新的序列开始编码。而普通I帧不具有随机访问的能力,这个功能则由IDR承担,在解码器中,一旦收到一个IDR帧,就会立即清理参考帧缓冲区,并将IDR帧作为被参考的帧。
在视频播放时,播放器一般都支持随机seek(拖动)到指定位置,而播放器直接选择到指定位置附近的 IDR 帧进行播放最为便捷,因为可以明确知道该 IDR 帧之后的所有帧都不会引用其之前的其他 I 帧,从而避免较为复杂的反向解析。
比如在对同一个视频进行多码率转码时,如果指定 IDR 帧对齐(IDR Frame Alignment),则意味着所有输出视频的 IDR 帧在时间点、帧内容方面都保持精确同步,此时播放器便可实现多码率视频平滑切换,从而不会出现较为明显的切换卡顿。
什么是GOP?gop_size值如何设置画质会更好?
GOP(Group of Pictures)即画面组,一个GOP就是一组连续的画面。GOP是序列中的一个图片集,用来辅助随机存取。GOP的第一个图像必须为I帧,这样就能保证GOP不需要参考其他图像,可以独立解码。
通常在为编码器设置参数的时候,必须要设置gop_size的值,其代表的是两个I帧之间的帧数目。一个GOP中容量最大的帧就是I帧,所以相对来讲,gop_size设置得越大,整个画面的质量就会越好,但是在解码端必须从接收到的第一个I帧开始才可以正确解码出原始图像,否则会无法正确解码。在提高视频质量的技巧中,还有个技巧是多使用B帧,使用B帧能节省大量空间,节省出来的空间可以用来更多地保存I帧,这样就能在相同的码率下提供更好的画质,所以根据不同的业务场景,要适当地设置gop_size的大小,以得到更高质量的视频。
OpenGOP & CloseGOP表示什么?
OpenGOP:一个GOP里面的某一帧在解码时要依赖于相邻GOP中的某一些帧,如下图,末尾的两个B帧需要依赖下一个GOP中的I帧进行解码。
ClosedGOP:帧间预测均在GOP中进行,下图展示的是两个CloseGOP的例子。
在HLS、DASH等自适应流媒体的场景下,为了实现码流之间的无缝切换,需要使用ClosedGOP,另外,针对部分手机的硬件解码器无法很好地支持OpenGOP,也可直接关闭OpenGOP。
视频流中的DTS和PTS又是什么?
DTS主要用于视频的解码,全称是Decoding Time Stamp, 为解码时间戳。
PTS主要用于解码阶段进行视频的同步和输出,全称是Presentation Time Stamp,为显示时间戳。
在没有B帧的情况下,DTS和PTS的输出顺序是一样的。因为B帧的双向预测打乱了解码和显示的顺序,所以一旦存在B帧,PTS与DTS势必就会不同。在FFmpeg中使用AVPacket结构体来描述解码前或编码后的压缩数据,用AVFrame结构体来描述解码后或编码前的原始数据。对于视频来说,AVFrame就是视频的一帧图像,这帧图像什么时候显示给用户,取决于它的PTS。DTS是AVPacket里的一个成员,表示该压缩包应该在什么时候被解码,如果视频里各帧的编码是按输入顺序(显示顺序)依次进行的,那么解码和显示时间应该是一致的,但是事实上,在大多数编解码标准中,编码顺序和输入顺序并不一致,于是才会需要PTS和DTS这两种不同的时间戳。