解析h264帧的sps和pps

一 h264视频流只有I帧才有sps和pps头

编码时候有一个参数选项,配置是否每个IDR前面都带有sps和pps信息。
二 h264视频流的sps和pps中我们主要关注哪些信息?
分辨率,profile类型,参考帧个数
三 x264中的sps和pps结构体
typedef struct
{
    int i_id;
    int i_profile_idc;//profile ID
    int i_level_idc;//编码level
    int b_constraint_set0;
    int b_constraint_set1;
    int b_constraint_set2;
    int b_constraint_set3;
    int i_log2_max_frame_num;
    int i_poc_type;
    /* poc 0 */
    int i_log2_max_poc_lsb;
    int i_num_ref_frames;//参考帧个数
    int b_gaps_in_frame_num_value_allowed;
    int i_mb_width;//分辨率
    int i_mb_height;
    int b_frame_mbs_only;
    int b_mb_adaptive_frame_field;
    int b_direct8x8_inference;
    int b_crop;
    struct
    {
        int i_left;
        int i_right;
        int i_top;
        int i_bottom;
    } crop;
    int b_vui;
    struct
    {
        int b_aspect_ratio_info_present;
        int i_sar_width;
        int i_sar_height;
        int b_overscan_info_present;
        int b_overscan_info;
        int b_signal_type_present;
        int i_vidformat;
        int b_fullrange;
        int b_color_description_present;
        int i_colorprim;
        int i_transfer;
        int i_colmatrix;
        int b_chroma_loc_info_present;
        int i_chroma_loc_top;
        int i_chroma_loc_bottom;
        int b_timing_info_present;
        uint32_t i_num_units_in_tick;
        uint32_t i_time_scale;
        int b_fixed_frame_rate;
        int b_nal_hrd_parameters_present;
        int b_vcl_hrd_parameters_present;
        struct
        {
            int i_cpb_cnt;
            int i_bit_rate_scale;
            int i_cpb_size_scale;
            int i_bit_rate_value;
            int i_cpb_size_value;
            int i_bit_rate_unscaled;
            int i_cpb_size_unscaled;
            int b_cbr_hrd;
            int i_initial_cpb_removal_delay_length;
            int i_cpb_removal_delay_length;
            int i_dpb_output_delay_length;
            int i_time_offset_length;
        } hrd;
        int b_pic_struct_present;
        int b_bitstream_restriction;
        int b_motion_vectors_over_pic_boundaries;
        int i_max_bytes_per_pic_denom;
        int i_max_bits_per_mb_denom;
        int i_log2_max_mv_length_horizontal;
        int i_log2_max_mv_length_vertical;
        int i_num_reorder_frames;
        int i_max_dec_frame_buffering;
        /* FIXME to complete */
    } vui;
    int b_qpprime_y_zero_transform_bypass;
    int i_chroma_format_idc;
}x264_sps_t;
typedef struct
{
    int i_id;
    int i_sps_id;
    int b_cabac;//商编码类型,是否为cabac
    int b_pic_order;
    int i_num_slice_groups;
    int i_num_ref_idx_l0_default_active;
    int i_num_ref_idx_l1_default_active;
    int b_weighted_pred;
    int b_weighted_bipred;
    int i_pic_init_qp;//初始qp
    int i_pic_init_qs;
    int i_chroma_qp_index_offset;
    int b_deblocking_filter_control;
    int b_constrained_intra_pred;
    int b_redundant_pic_cnt;
    int b_transform_8x8_mode;
    int i_cqm_preset;
    const uint8_t *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */
} x264_pps_t;
四 解析sps中的profile类型和分辨率信息
static int u(int bitCount,char *buf,int &startbit)
{
int ret = 0;
for(int i = 0;i<bitCount;i++)
{
ret *=2;
if(buf[startbit/8]&(0x80>>(startbit%8)))
{
ret += 1;
}
startbit ++;
}
return ret;
}//取几个bit值
//取到bit0为止
static int Ue(char *buf,int len,int& startbit)
{
int nZeroNum = 0;
while(startbit < len * 8)
{
if(buf[startbit/8]&(0x80>>(startbit%8)))
{
break;
}
nZeroNum ++;
startbit ++;
}
startbit ++;
int ret = 0;
for(int i = 0;i<nZeroNum;i++)
{
ret *= 2;
if(buf[startbit/8]&(0x80 >> (startbit%8)))
{
ret +=1;
}
startbit ++;
}
return (1<<nZeroNum) -1 + ret;
}
static int Se(char *buf,int len,int& startbit)
{
int UeVal = Ue(buf,len,startbit);
double k = UeVal;


int nValue = ceil(k/2);


if(UeVal%2 == 0)
{
nValue =- nValue;
}
return nValue;
}

static int parse_sps(char *buf,int len)
{
if(buf==NULL||len == 0)
{
return -1;
}
int StartBit = 0;
int forbid_bit = u(1,buf,StartBit);
int nalref_idc=u(2,buf,StartBit);
int nal_unit_type = u(5,buf,StartBit);
if(nal_unit_type == 7)//sps   nalu类型
{
int profile_idc = u(8,buf,StartBit);//profile类型
int constraint_set0_flag = u(1,buf,StartBit);
int constraint_set1_flag = u(1,buf,StartBit);
int constraint_set2_flag = u(1,buf,StartBit);
int constraint_set3_flag = u(1,buf,StartBit);
int reseved_zero_4bits =u(4,buf,StartBit);
int idc_level = u(8,buf,StartBit);//idc 等级
if(profile_idc == 100
||profile_idc== 110
||profile_idc== 122
||profile_idc== 144)
{
int chroma_format_idc = Ue(buf,len,StartBit);
if(chroma_format_idc == 3)
{
int residual_colour_transform_flag=u(1,buf,StartBit);
}

int bit_depth_luma_minus8=Ue(buf,len,StartBit);
int bit_depth_chroma_minus8=Ue(buf,len,StartBit);
int qpprime_y_zero_transform_bypass_flag=u(1,buf,StartBit);
int seq_scaling_matrix_present_flag=u(1,buf,StartBit);
int seq_scaling_list_present_flag[8];
if( seq_scaling_matrix_present_flag )
{
for( int i = 0; i < 8; i++ ) 
{
seq_scaling_list_present_flag[i]=u(1,buf,StartBit);
}
}
}
int log2_max_frame_num_minus4 = Ue(buf,len,StartBit);
int pic_order_cnt_type = Ue(buf,len,StartBit);
if(pic_order_cnt_type == 0)
{
int log2_max_pic_order_cnt_lsb_minus4 = Ue(buf,len,StartBit);
}
else if(pic_order_cnt_type == 1)
{
int delta_pic_order_always_zero_flag=u(1,buf,StartBit);
int offset_for_non_ref_pic=Se(buf,len,StartBit);
int offset_for_top_to_bottom_field=Se(buf,len,StartBit);
int num_ref_frames_in_pic_order_cnt_cycle=Ue(buf,len,StartBit);
int *offset_for_ref_frame=new int[num_ref_frames_in_pic_order_cnt_cycle];
for(int i = 0;i<num_ref_frames_in_pic_order_cnt_cycle;i++)
{
offset_for_ref_frame[i]=Se(buf,len,StartBit);
}
delete [] offset_for_ref_frame;
}
int num_ref_frames=Ue(buf,len,StartBit);
int gaps_in_frame_num_value_allowed_flag=u(1,buf,StartBit);
int pic_width_in_mbs_minus1=Ue(buf,len,StartBit);
int pic_height_in_map_units_minus1=Ue(buf,len,StartBit);
int Width=(pic_width_in_mbs_minus1+1)*16;//宽度
int Height=(pic_height_in_map_units_minus1+1)*16;//高度
return nal_unit_type;
}
else
{
return nal_unit_type;
}
return nal_unit_type;
}


阅读更多

没有更多推荐了,返回首页