一 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
{
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
{
ret *= 2;
if(buf[startbit/8]&(0x80 >> (startbit%8)))
{
ret +=1;
}
startbit ++;
}
return (1<}
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
{
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;
}