原文链接https://blog.jianchihu.net/intel-media-sdk-remove-unused.html。
使用Intel media SDK硬编码H264数据时,生成的每一帧H264数据都包含Access unit delimiter+Picture parameter set+Additional information (SEI)。如下图是使用默认参数生成的一个非IDR帧H264数据。
IDR帧数据结构如下:
根据nal uint type表
可知:
默认编码IDR帧结构:0x00 00 00 01 09(分隔符)|| 0x00 00 00 01 27(SPS)|| 0x00 00 00 01 28(PPS)|| 0x00 00 00 01 06(SEI)|| 0x00 00 01 25(IDR)
默认编码非IDR帧结构:0x00 00 00 01 09(分隔符)|| 0x00 00 00 01 28(PPS)|| 0x00 00 00 01 06(SEI)|| 0x00 00 01 21(非IDR)
但是默认编码有个问题,不是所有播放器可以支持直接播放,测了下VLC不支持(以前文章说过VLC播放带SEI的视频花屏问题),PotPlayer可以播放,这个问题在于编码出来的每帧数据都多了分隔符与SEI以及PPS,不是所有的播放器都去解析这些头部,这方面NVIDIA Video Codec硬编码就简单多了,IDR帧结构就SPS+PPS+IDR,非IDR帧就一个头部。所以为了兼容大多数播放器我们需要去掉多余的分隔符、SEI以及PPS信息,这些信息用途不大,PPS没必要每帧都带,反而增加数据量。如何去除呢,一种方法是手动解析这些头部,然后手动去除,另一种方法是使用编码的扩展参数,这个编码扩展参数如果没认真研究官方文档,还真不知道怎么用。
如下是编码扩展参数如何使用的代码。代码中我们将设置的参数放到一个数组中,然后传递给编码参数mfxVideoParam的ExtParam成员。
mfxVideoParam mfxEncParams;
//其他参数设置
//.........
mfxExtCodingOption option;
memset(&option, 0, sizeof(option));
option.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
option.Header.BufferSz = sizeof(option);
//option.RefPicMarkRep = MFX_CODINGOPTION_ON;
option.NalHrdConformance = MFX_CODINGOPTION_OFF;
option.PicTimingSEI = MFX_CODINGOPTION_OFF;
option.AUDelimiter = MFX_CODINGOPTION_OFF;
mfxExtCodingOption2 option2;
memset(&option2, 0, sizeof(option2));
option2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2;
option2.Header.BufferSz = sizeof(option2);
option2.RepeatPPS = MFX_CODINGOPTION_OFF;
std::vector<mfxExtBuffer*> m_EncExtParams;
m_EncExtParams.push_back((mfxExtBuffer *)&option);
m_EncExtParams.push_back((mfxExtBuffer *)&option2);
mfxEncParams.ExtParam = &m_EncExtParams[0];
mfxEncParams.NumExtParam = m_EncExtParams.size();
mfxExtCodingOption.PicTimingSEI:
Set this flag to insert the picture timing SEI with pic_struct syntax element. See sub-clauses D.1.2 and D.2.2 of the ISO /IEC 14496-10 specification for the definition of this syntax element. See the
CodingOptionValue enumerator for values of this option. The default value is ON. 也就是这个成员用于在每帧插入图像时序SEI信息,默认是开启的。
mfxExtCodingOption.AUDelimite:
Set this flag to insert the Access Unit Delimiter NAL. See the CodingOptionValue enumerator for values of this option.该标志用于插入分隔符。
mfxExtCodingOption2.RepeatPPS:
This flag controls picture parameter set repetition in AVC encoder. Turn ON this flag to repeat PPS with each frame. See the CodingOptionValue enumerator for values of this option. The default value is ON. This parameter is valid only during initialization.用于设置AVC编码器在每一帧编码中插入PPS。默认是开启的。
通过关闭如上编码参数,即可去除多余的数据,编码生成”简洁”的H264帧。