H.264---序列参数集(SPS)---宽高获取

本文详细介绍了H.264编码中Sequence Parameter Set (SPS)的结构,特别是如何从SPS中获取视频的宽高和帧率。内容涉及SPS的NAL单元、VUI_parameters子结构、hrd_parameters子结构,以及frame_cropping_flag在不同情况下的宽高计算方法。同时,还讨论了H.265编码中分辨率的计算方式,并指出了解析SPS以获取视频帧率的关键信息。
摘要由CSDN通过智能技术生成

Sequence Paramater Set(NAL Unit=7)

SPS和PPS一般处于码流的起始位置,但也可能出现在码流中间,主要原因是:
1、解码器需要在码流中间开始解码;
2、编码器在编码的过程中改变了码流的参数(如图像分辨率等);

SPS结构(H264文档7.3.2.1)

/**
Sequence Parameter Set
@see 7.3.2.1 Sequence parameter set RBSP syntax
*/
typedef struct
{
   
   int profile_idc;                                    // u(8)
   /*  —————————— 编码级别的制约条件 Start  —————————— */
   int constraint_set0_flag;                           // u(1)
   int constraint_set1_flag;                           // u(1)
   int constraint_set2_flag;                           // u(1)
   int constraint_set3_flag;                           // u(1)
   int constraint_set4_flag;                           // u(1)
   int constraint_set5_flag;                           // u(1)
   int reserved_zero_2bits;                            // u(2)
   /*  —————————— 编码级别的制约条件 End  —————————— */
   
   int level_idc;                                      // u(8)
   int seq_parameter_set_id;                           // ue(v)
   
   /*  —————————— 几个罕见级别对应的句法元素 Start  —————————— */
   /*
    if( profile_idc = = 100 | | profile_idc = = 110 | |
    profile_idc = = 122 | | profile_idc = = 244 | | 
	profile_idc = = 44 | | profile_idc = = 83 | | 
	profile_idc = = 86 | | profile_idc = = 118 | | 
	profile_idc = = 128 | | profile_idc = = 138 | | 
	profile_idc = = 139 | | profile_idc = = 134 | | 
	profile_idc = = 135 ) {
    */
       int chroma_format_idc;                                  // ue(v)
//      if( chroma_format_idc = = 3 )
           int separate_colour_plane_flag;                     // u(1)
       int bit_depth_luma_minus8;                              // ue(v)
       int bit_depth_chroma_minus8;                            // ue(v)
       int qpprime_y_zero_transform_bypass_flag;               // u(1)
   
       int seq_scaling_matrix_present_flag;                    // u(1)
//      if( seq_scaling_matrix_present_flag )
//          for( i = 0; i < ( ( chroma_format_idc != 3 ) ? 8 : 12 ); i++ ) {
   
               int seq_scaling_list_present_flag[12]; // 最大值12数组   // u(1)
//              if( seq_scaling_list_present_flag[ i ] )
//                  if( i < 6 )
                       int ScalingList4x4[6][16]; // 二维数组遍历
                       int UseDefaultScalingMatrix4x4Flag[6];
//                  else
                       int ScalingList8x8[6][64];
                       int UseDefaultScalingMatrix8x8Flag[6];
   /*  —————————— 几个罕见级别对应的句法元素 End  —————————— */
   
   /*  —————————— 用来计算POC的句法元素 Start  —————————— */
   int log2_max_frame_num_minus4;                              // ue(v)
   int pic_order_cnt_type;                                     // ue(v)
   
//  if( pic_order_cnt_type = = 0 )
       int log2_max_pic_order_cnt_lsb_minus4;                  // ue(v)
//  else if( pic_order_cnt_type = = 1 ) {
   
       int delta_pic_order_always_zero_flag;                   // u(1)
       int offset_for_non_ref_pic;                             // se(v)
       int offset_for_top_to_bottom_field;                     // se(v)
       int num_ref_frames_in_pic_order_cnt_cycle;              // ue(v)
//      for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
           int offset_for_ref_frame[256]; // 最大值256数组       // se(v)
   /*  —————————— 用来计算POC的句法元素 End  —————————— */
   
   int max_num_ref_frames;                                     // ue(v)
   int gaps_in_frame_num_value_allowed_flag;                   // u(1)
   
   /*  —————————— 图像宽高相关 Start  —————————— */
   int pic_width_in_mbs_minus1;                                // ue(v)
   int pic_height_in_map_units_minus1;                         // ue(v)
   int frame_mbs_only_flag;                                    // u(1)
//  if( !frame_mbs_only_flag )
       int mb_adaptive_frame_field_flag;                       // u(1)
   /*  —————————— 图像宽高相关 End  —————————— */
   
   int direct_8x8_inference_flag;                              // u(1)
   
   /*  —————————— 解码后图像剪裁的几个句法元素 Start  —————————— */
   int frame_cropping_flag;                                    // u(1)
//  if( frame_cropping_flag ) {
   
       int frame_crop_left_offset;                             // ue(v)
       int frame_crop_right_offset;                            // ue(v)
       int frame_crop_top_offset;                              // ue(v)
       int frame_crop_bottom_offset;                           // ue(v)
   /*  —————————— 解码后图像剪裁的几个句法元素 End  —————————— */
   
   int vui_parameters_present_flag;                            // u(1)
//  if( vui_parameters_present_flag )
       vui_parameters_t vui_parameters; // Annex E E.1.1
} sps_t;

要注意里面有些句法元素,需要结合它前后的语法结构,和它的语义推敲得来。比如scaling_list相关几个数组,它们的数组大小是根据for循环的遍历次数得来。而且ScalingList4x4和ScalingList8x8被定义为了二维数组,因为在调用scaling_list()时,传进去的ScalingList4x4[i]本身是个一维数组,因此ScalingList4x4是二维数组。

而其中数组offset_for_ref_frame[]的大小,是由for循环的次数num_ref_frames_in_pic_order_cnt_cycle决定的,我们已经知道num_ref_frames_in_pic_order_cnt_cycle的取值为[0,255],因此数组offset_for_ref_frame[]的大小就是256。

SPS中的子结构体VUI_parameters(见E.1.1)

/**
vui_parameters()
@see Annex E E.1.1 VUI parameters syntax
*/
typedef struct {
   
   int aspect_ratio_info_present_flag;                 // u(1)
//  if( aspect_ratio_info_present_flag ) {
   
       int aspect_ratio_idc;                           // u(8)
//      if( aspect_ratio_idc = = Extended_SAR ) {
   
           int sar_width;                              // u(16)
           int sar_height;                             // u(16)
   
   int overscan_info_present_flag;                     // u(1)
//  if( overscan_info_present_flag )
       int overscan_appropriate_flag;                  // u(1)
   int video_signal_type_present_flag;                 // u(1)
   
//  if( video_signal_type_present_flag ) {
   
       int video_format;                               // u(3)
       int video_full_range_flag;                      // u(1)
       int colour_d
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值