H264编码的场格式编码
视频的帧和场是由于历史原因引入的,早期的视频采集和输出设备效率不高导致。
在CIF,D1图像大小的标清年代,CRT显示器传输频宽不够,逐行扫描的方法通常从上到下地扫描每帧图像。这个过程消耗的时间比较长,阴极射线的荧光衰减将造成人视觉的闪烁感觉。当频宽受限,以至于不可能快到使用逐行扫描而且没有闪烁效应时,通常采用一种折衷的办法,即每次只传输和显示一半的扫描线,即场。一场只包含偶数行(即偶场)或者奇数行(即奇场)扫描线。由于视觉暂留效应,人眼不会注意到两场只有一半的扫描行,而会看到完整的一帧。
摄像机采集的方式和隔行扫描显示的方式是完全相同的。当摄像机采集图像时,偶场和奇场不是同时采集的。例如在一个每秒50场的摄像机中,第122行和124行的采集在第121行和123行的采集大约1/50秒之后进行。所以如果把一个偶场和奇场简单的拼合在一起,水平方向的运动会造成两场边界上不能完美的拼合。
随着时代的进步,当代的显示器,电视,摄像机,由于逐行显示和采集的刷新率的提高,已经不会再感觉到闪烁现象,因此,隔行扫描技术逐渐被取代。
但历史带来的遗留问题也遗留了下来,虽然现在一些视频采集和播放设备能支持高清,超高清和逐行扫描,但隔行这种场格式还是保留了下来。
H264对帧场的支持
H264标准也是标清时代的产物,所以H264编码器是支持帧和场的。
H264编码序列帧、场编码方式
1.固定帧编码
整个视频序列的帧始终采用帧编码方式。这是我们最常用的方式,高清时代都基本都是帧编码。这是我们最常用的一种模式。
2.固定场编码
整个视频序列中帧被分成两个场(顶场和底场)独立编码。
1) I帧可编码成 II, IP
II是指两个I场,即第一个I帧是上半场,第二个I帧是下半场。
IP是指编码成IP,即第一个I帧是上半场,第二个P帧内容是下半场。
2)P帧可编码成PP、PB.
PP是指第一个P帧是上半场,第二个P帧是下半场。
PB是指第一个P帧是上半场,第二个B帧内容是下半场。
3) B帧可编码成两个B场,BB
BB是指第一个B帧是上半场,第二个B帧是下半场。
3.图像级帧、场自适应编码 (PAFF)
视频序列以帧为单位,被编码成一个帧或两个场,自适应选择原则是根据采用该种编码方式的每一帧的RD值。
这种模式在实际H264编码中用的很少,除非是为了算法研究,做应用的同学们可以忽略。
4.宏块级帧、场自适应(MBAFF)
视频序列以宏块为单位,MBAFF采用了宏块级帧场自适应.,宏块级采用了宏块对(MBP)为基本编码单元。
同样这种模式在实际H264编码中用的很少,除非是为了算法炫技,做应用的同学们可以忽略。
帧场在H264码流里的标志位
在H.264的码流里有四个参数来描述上一小节的内容。
frame_mbs_only_flag
标识位说明宏块的编码方式。当该标识位为0时,宏块可能为帧编码或场编码;该标识位为1时,所有宏块都采用帧编码。根据该标识位取值不同,PicHeightInMapUnits的含义也不同,为0时表示一场数据按宏块计算的高度,为1时表示一帧数据按宏块计算的高度。
按照宏块计算的图像实际高度FrameHeightInMbs的计算方法为:
FrameHeightInMbs = ( 2 − frame_mbs_only_flag ) * PicHeightInMapUnits
mb_adaptive_frame_field_flag
标识位,说明是否采用了宏块级的帧场自适应编码。当该标识位为0时,不存在帧编码和场编码之间的切换;当标识位为1时,宏块可能在帧编码和场编码模式之间进行选择。
field_pic_flag
标识位说明当前图像是帧编码(0)还是场编码(1)。这个元素在同一图像的所有片中应具有相同值。仅当序列参数集中的frame_mbs_only_flag为0时,这个元素才会出现在码流中。
bottom_field_flag
标识位说明当前的场是顶场还是底场。值为1 时表示当前图像是属于底场;等于 0 时表示当前图像是属于顶场。这个标识位仅当field_pic_flag存在且为1时,才会出现在码流中。
frame_mbs_only_flag | mb_adaptive_frame_field_flag | field_pic_flag | 模式 |
1 | 无 | 无 | 帧编码 |
0 | 0 | 0 | 帧编码 |
0 | 0 | 1 | 场编码 |
0 | 1 | 0 | 帧场自适应 |
0 | 1 | 1 | 场编码 |
H264场格式码流例子
从上面的例子码流标识中可以看到
frame_mbs_only_flag = 0 ; //视频内宏块可能为帧编码或场编码
mb_adaptive_frame_field_flag = 0; //帧编码和场编码之间没有自适应切换
field_pic_flag = 1; //确定当前图像是场编码,I帧是顶场,P帧是低场。用的是IP和PP模式
目前有的解码器能支持顶场和低场分别送给解码器解码,有的解码器不支持,需要把上下半场合在一起送给解码器解码才能正常解码,输出完整图像。