H.264主要有五种编码帧:
I(IDR帧)、i(非IDR I帧)、P(P帧)、B(参考B帧)、b(非参考B帧)。
GOP(Group of picture 图像组),指两个I帧之间的所有帧结构。x264里面决定GOP长度的参数有i_keyint_max,i_keyint_min,i_scenecut_threshold,b_open_gop.
例如:
i_keyint_max = 10;
i_keyint_min = 3;
i_scenecut_threshold = 0;
F00 F01 F02 F03 F04 F05 F06 F07 F08 F09 F10 F11 F12 F13 F14 F15 F16 F17
IDR ... IDR ...
每10帧强制一个IDR帧, 如果i_scenecut_threshold = 40; 并检测到F06场景切换则
F00 F01 F02 F03 F04 F05 F06 F07 F08 F09 F10 F11 F12 F13 F14 F15 F16 F17
IDR IDR IDR
发现一个场景切换,并且与前一个IDR距离大于i_keyint_min,插入IDR并重新计数IDR距离
如果i_scenecut_threshold = 40; 并检测到F02场景切换则
F00 F01 F02 F03 F04 F05 F06 F07 F08 F09 F10 F11 F12 F13 F14 F15 F16 F17
IDR I IDR
发现一个场景切换,并且与前一个IDR距离小于i_keyint_min,插入I帧并重新计数IDR距离
如果i_scenecut_threshold = 40; 并检测到F02 F07场景切换则
F00 F01 F02 F03 F04 F05 F06 F07 F08 F09 F10 F11 F12 F13 F14 F15 F16 F17
IDR I IDR IDR
第一个场景切换距离小于i_keyint_min插入I帧,第二个场景切换距离前一个I帧距离大于i_keyint_min,插入IDR帧,并从新计数
码流里面包含B帧的时候才会出现open-GOP。一个GOP里面的某一帧在解码时要依赖于前一个GOP的某些帧,这个GOP就称为open-GOP。有些解码器不能完全支持open-GOP码流,例如蓝光解码器,因此在x264里面open-GOP是默认关闭的。对于解码端,接收到的码流如果如下:
I0 B0 B1 P0 B2 B3...
这就是一个open-GOP码流(I帧后面紧跟B帧)。因此B0 B1的解码需要用到I0前面一个GOP的数据,B0 B1的dts是小于I0的。如果码流如下:
I0 P0 B0 B1 P1 B2 B3...
这就是一个close-GOP码流,I0后面所有帧的解码不依赖于I0前面的帧,I0后面所有帧的dts都比I0的大。如果码流是
IDR0 B0 B1 P0 B2 B3...
那个这个GOP是close-GOP,B0,B1虽然dst比IDR0小,但编解码端都刷新了参考缓冲,B0,B1参考不到前向GOP帧。
对于编码端,如果编码帧类型决定如下:
...P0 B1 B2 P3 B4 B5 I6
这就会输出open-Gop码流
P0 P3 B1 B2 I6 B4 B5...,
B4 B5的解码依赖P3。如果编码帧类型决定如下
...P0 B1 B2 P3 B4 P5 I6
这样就不会输出open-GOP码流
P0 P3 B1 B2 P5 B4 I6...
两者区别在于I6前面的第5帧是设置为B帧还是P帧,如果一个GOP的最后一帧(上例中是第5帧)设置为B帧,这个码流就是open-GOP,设置为P帧就是close-GOP。由于B帧压缩性能好于P帧,因此open-GOP在编码性能上稍微优于close-GOP,但为了兼容性和少一些麻烦,还是把opne-GOP关闭的好。