【HEVC学习与研究】14.HEVC解码中VPS参数集解析
2014-12-16 22:17
267 查看
“视频参数集”结构用于解释编码过的视频序列的整体结构,包括时域子层依赖关系等。HEVC中加入该结构的主要目的是兼容标准在系统的多子层方面的扩展,处理比如未来的可分级或者多视点视频使用原先的解码器进行解码但是其所需的信息可能会被解码器忽略的问题。
对于给定视频序列的某一个子层,无论其SPS相不相同都共享一个VPS。其主要包含的信息有:1、多个子层或操作点共享的语法元素;2、档次和级别等会话关键信息;3、其他不属于SPS的操作点特定信息。
博文13中列出了码流的二进制结构。在我们自己编码生成的码流中,第一个NAL单元携带的就是VPS信息。如何得知?通过解析nal单元头可以提取nal类型字段。解析这个VPS nal单元的具体流程为:
(1)在完成配置参数的解析之后,TAppDecTop::decode()这个函数正式进行解码过程。在编码码流未到结束的情况下,byteStreamNALUnit(bytestream, nalUnit, stats);这个函数不断在码流中读取NAL数据。该函数的功能上一篇博文曾经提到过,主要功能是给_byteStreamNALUnit(bs, nalUnit, stats)这个函数戴一层TT(O(∩_∩)O哈哈~),外加返回一个元素的个数值。
(2)_byteStreamNALUnit(bs, nalUnit, stats)这个函数中,寻找码流中的NAL起始位0x00000001,并将下一个nal起始位前面的字节检出放入nalUnit这个单元中。
(3)read(nalu, nalUnit)处理nalUnit的数据,保留其中的有效数据,舍弃掉其中的填充部分,主要通过convertPayloadToRBSP函数实现。readNalUnitHeader (InputNALUnit& nalu)函数解析nal的数据头,在该函数中可以很明白地看到从码流中取出了nal的0位、nal类型、6位0保留字和时间id。该码流中的nal头的二进制码为0x4001,二进制结构为0100
0000 0000 0001,与上篇博文中的NAL头数据结构对比可知,其nal type = 32,temporal id = 0;
(4)bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay)解析NAL的数据。该函数的主题是一个switch-case语句,通过判断不同的nal类型进行不同的解码操作。上一步中nal type = 32 = NAL_UNIT_VPS,因此调用xDecodeVPS()解析该NAL。
流程:xDecodeVPS()--->m_cEntropyDecoder.decodeVPS( vps )--->m_pcEntropyDecoderIf->parseVPS(pcVPS)
parseVPS(pcVPS)主要使用三个宏从码流中读取数据:READ_CODE()读取指定长度的比特位,READ_FLAG()当前位置下一位标识位,READ_UVLC()按照变长码方式从码流中读取数据。函数所读取的字段可以参考标准文档的说明(提案JCT-VC
L1003)第43页。
部分参数的解释以及本例中的取值,【本例取值】:
vps_video_parameter_set_id:其他语法元素所参考的VPS编号,【0】;
vps_reserved_three_2bits:保留位,指定为3,【3】;
vps_max_layers_minus1:当前版本保留,值为0,用于未来的3D和可分级扩展标准使用,【0】;
vps_max_sub_layers_minus1:这个值表示比特流中可以支持最大数目的时域子层数目减1,取值范围为0到6,也就是最大可以支持7个子层,【0】;
vps_temporal_id_nesting_flag:当前一个参数vps_max_sub_layers_minus1为0(即不支持时域子层)时,这个参数应该为1;vps_max_sub_layers_minus1非0时,指定是否对编码视频序列的帧间预测添加限制。用于子层切换过程中,【1】。
vps_reserved_0xffff_16bits:两个字节的保留位,全部为1,【255,255】;
vps_sub_layer_ordering_info_present_flag:为1,vps_max_dec_pic_buffering_minus1[ i ],
vps_max_num_reorder_pics[ i ]和 vps_max_latency_increase_plus1[ i ]适用于vps_max_sub_layers_minus1 + 1个子层;为0,这些参数适用于所有子层,【1】;
vps_max_dec_pic_buffering_minus1:指定所需的最大解码图像缓存的数量,【0】;
vps_max_num_reorder_pics和vps_max_latency_increase_plus1:指定按照解码顺序在某一帧之后,而显示顺序在某一帧之前的帧的最大数量;这两个参数的区别暂时还没看明白,【0,0】;
vps_max_layer_id:CVS中所有NAL单元的最大允许的nuh_layer_id值。
vps_num_layer_sets_minus1:由VPS指定的图层组的数量-1;当前标准中指定为0;
layer_id_included_flag[][]:表示nuh_layer_id与layerSetLayerIdList[]的包含关系;
vps_timing_info_present_flag:标识该VPS是否包含几个时间相关参数,【0】;
vps_extension_flag:标识该VPS是否包含扩展信息,【0】。
对于给定视频序列的某一个子层,无论其SPS相不相同都共享一个VPS。其主要包含的信息有:1、多个子层或操作点共享的语法元素;2、档次和级别等会话关键信息;3、其他不属于SPS的操作点特定信息。
博文13中列出了码流的二进制结构。在我们自己编码生成的码流中,第一个NAL单元携带的就是VPS信息。如何得知?通过解析nal单元头可以提取nal类型字段。解析这个VPS nal单元的具体流程为:
(1)在完成配置参数的解析之后,TAppDecTop::decode()这个函数正式进行解码过程。在编码码流未到结束的情况下,byteStreamNALUnit(bytestream, nalUnit, stats);这个函数不断在码流中读取NAL数据。该函数的功能上一篇博文曾经提到过,主要功能是给_byteStreamNALUnit(bs, nalUnit, stats)这个函数戴一层TT(O(∩_∩)O哈哈~),外加返回一个元素的个数值。
(2)_byteStreamNALUnit(bs, nalUnit, stats)这个函数中,寻找码流中的NAL起始位0x00000001,并将下一个nal起始位前面的字节检出放入nalUnit这个单元中。
(3)read(nalu, nalUnit)处理nalUnit的数据,保留其中的有效数据,舍弃掉其中的填充部分,主要通过convertPayloadToRBSP函数实现。readNalUnitHeader (InputNALUnit& nalu)函数解析nal的数据头,在该函数中可以很明白地看到从码流中取出了nal的0位、nal类型、6位0保留字和时间id。该码流中的nal头的二进制码为0x4001,二进制结构为0100
0000 0000 0001,与上篇博文中的NAL头数据结构对比可知,其nal type = 32,temporal id = 0;
(4)bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay)解析NAL的数据。该函数的主题是一个switch-case语句,通过判断不同的nal类型进行不同的解码操作。上一步中nal type = 32 = NAL_UNIT_VPS,因此调用xDecodeVPS()解析该NAL。
流程:xDecodeVPS()--->m_cEntropyDecoder.decodeVPS( vps )--->m_pcEntropyDecoderIf->parseVPS(pcVPS)
parseVPS(pcVPS)主要使用三个宏从码流中读取数据:READ_CODE()读取指定长度的比特位,READ_FLAG()当前位置下一位标识位,READ_UVLC()按照变长码方式从码流中读取数据。函数所读取的字段可以参考标准文档的说明(提案JCT-VC
L1003)第43页。
部分参数的解释以及本例中的取值,【本例取值】:
vps_video_parameter_set_id:其他语法元素所参考的VPS编号,【0】;
vps_reserved_three_2bits:保留位,指定为3,【3】;
vps_max_layers_minus1:当前版本保留,值为0,用于未来的3D和可分级扩展标准使用,【0】;
vps_max_sub_layers_minus1:这个值表示比特流中可以支持最大数目的时域子层数目减1,取值范围为0到6,也就是最大可以支持7个子层,【0】;
vps_temporal_id_nesting_flag:当前一个参数vps_max_sub_layers_minus1为0(即不支持时域子层)时,这个参数应该为1;vps_max_sub_layers_minus1非0时,指定是否对编码视频序列的帧间预测添加限制。用于子层切换过程中,【1】。
vps_reserved_0xffff_16bits:两个字节的保留位,全部为1,【255,255】;
vps_sub_layer_ordering_info_present_flag:为1,vps_max_dec_pic_buffering_minus1[ i ],
vps_max_num_reorder_pics[ i ]和 vps_max_latency_increase_plus1[ i ]适用于vps_max_sub_layers_minus1 + 1个子层;为0,这些参数适用于所有子层,【1】;
vps_max_dec_pic_buffering_minus1:指定所需的最大解码图像缓存的数量,【0】;
vps_max_num_reorder_pics和vps_max_latency_increase_plus1:指定按照解码顺序在某一帧之后,而显示顺序在某一帧之前的帧的最大数量;这两个参数的区别暂时还没看明白,【0,0】;
vps_max_layer_id:CVS中所有NAL单元的最大允许的nuh_layer_id值。
vps_num_layer_sets_minus1:由VPS指定的图层组的数量-1;当前标准中指定为0;
layer_id_included_flag[][]:表示nuh_layer_id与layerSetLayerIdList[]的包含关系;
vps_timing_info_present_flag:标识该VPS是否包含几个时间相关参数,【0】;
vps_extension_flag:标识该VPS是否包含扩展信息,【0】。
相关文章推荐
- 【HEVC学习与研究】15、HEVC解码中的SPS解析
- 【HEVC学习与研究】16、HEVC中的PPS解析
- 【HEVC学习与研究】18.HEVC的条带头解析
- HEVC学习与研究】11.HEVC参考解码器的设置及参数解析过程
- 【HEVC学习与研究】27、CABAC解析语法元素SAO
- 【HEVC学习与研究】30、解码Coding Unit数据
- 【HEVC学习与研究】30、解码Coding Unit数据
- 【HEVC学习与研究】28、第一帧第一个宏块的SAO部分完整解析结果
- 【HEVC学习与研究】44、HEVC量化系数的解析——反量化过程
- 【HEVC学习与研究】27、CABAC解析语法元素SAO
- 【HEVC学习与研究】11.HEVC参考解码器的设置及参数解析过程
- 【HEVC学习与研究】28、第一帧第一个宏块的SAO部分完整解析结果
- 【HEVC学习与研究】37、HM编码器的基本结构2:帧内编码部分的代码骨架
- 【HEVC学习与研究】34、HEVC参考软件HM中Intra预测参考像素的获取与管理
- HEVC学习与研究
- HEVC解码中的SPS解析
- 【ffmpeg学习】Tutorial 04: Spawning Threads 将解析线程与视频解码线程分开
- 【HEVC学习与研究】3、HEVC概览(3)