x264代码剖析(六):encode()函数之x264_encoder_headers()函数

x264代码剖析(六):encode()函数之x264_encoder_headers()函数

 

        encode()函数是x264的主干函数,主要包括x264_encoder_open()函数、x264_encoder_headers()函数、x264_encoder_encode()函数与x264_encoder_close()函数四大部分,其中x264_encoder_encode()函数是其核心部分,具体的H.264视频编码算法均在此模块。上一篇博文主要分析了x264_encoder_open()函数,本文主要学习x264_encoder_headers()函数。

 

        x264_encoder_headers()libx264的一个API函数,用于输出SPS/PPS/SEI这些H.264码流的头信息,如下图所示。它调用了下面的函数:

x264_sps_write():输出SPS

x264_pps_write():输出PPS

x264_sei_version_write():输出SEI

 



        下面对x264_encoder_headers()函数所涉及的函数进行介绍,首先就是SPSPPS的初始化工作;其次是x264_encoder_headers()函数的内容;最后就是x264_encoder_headers()函数中用于输出SPS/PPS/SEI这些H.264码流头信息的具体函数,即x264_sps_write()函数、x264_pps_write()函数与x264_sei_version_write()函数。

 

1SPSPPS的初始化函数x264_sps_init()x264_pps_init()

 

        x264_sps_init()根据输入参数生成H.264码流的SPSSequence Parameter Set,序列参数集)信息,即根据输入参数集x264_param_t中的信息,初始化了SPS结构体中的成员变量。该函数的定义位于encoder\set.c对应的代码如下:

 

初始化SPS
void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
{int csp = param->i_csp & X264_CSP_MASK;sps->i_id = i_id;sps->i_mb_width = ( param->i_width + 15 ) / 16;	//以宏块为单位的宽度sps->i_mb_height= ( param->i_height + 15 ) / 16;	//以宏块为单位的高度sps->i_chroma_format_idc = csp >= X264_CSP_I444 ? CHROMA_444 :csp >= X264_CSP_I422 ? CHROMA_422 : CHROMA_420;	//色度取样格式sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;//型profileif( sps->b_qpprime_y_zero_transform_bypass || sps->i_chroma_format_idc == CHROMA_444 )sps->i_profile_idc  = PROFILE_HIGH444_PREDICTIVE;	//YUV444的时候else if( sps->i_chroma_format_idc == CHROMA_422 )sps->i_profile_idc  = PROFILE_HIGH422;else if( BIT_DEPTH > 8 )sps->i_profile_idc  = PROFILE_HIGH10;else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )sps->i_profile_idc  = PROFILE_HIGH;	//高型 High Profile 目前最常见else if( param->b_cabac || param->i_bframe > 0 || param->b_interlaced || param->b_fake_interlaced || param->analyse.i_weighted_pred > 0 )sps->i_profile_idc  = PROFILE_MAIN;	//主型 elsesps->i_profile_idc  = PROFILE_BASELINE;	//基本型sps->b_constraint_set0  = sps->i_profile_idc == PROFILE_BASELINE;/* x264 doesn't support the features that are in Baseline and not in Main,* namely arbitrary_slice_order and slice_groups. */sps->b_constraint_set1  = sps->i_profile_idc <= PROFILE_MAIN;/* Never set constraint_set2, it is not necessary and not used in real world. */sps->b_constraint_set2  = 0;sps->b_constraint_set3  = 0;//级levelsps->i_level_idc = param->i_level_idc;if( param->i_level_idc == 9 && ( sps->i_profile_idc == PROFILE_BASELINE || sps->i_profile_idc == PROFILE_MAIN ) ){sps->b_constraint_set3 = 1; /* level 1b with Baseline or Main profile is signalled via constraint_set3 */sps->i_level_idc      = 11;}/* Intra profiles */if( param->i_keyint_max == 1 && sps->i_profile_idc > PROFILE_HIGH )sps->b_constraint_set3 = 1;sps->vui.i_num_reorder_frames = param->i_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0;/* extra slot with pyramid so that we don't have to override the* order of forgetting old pictures *///参考帧数量sps->vui.i_max_dec_frame_buffering =sps->i_num_ref_frames = X264_MIN(X264_REF_MAX, X264_MAX4(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames,param->i_bframe_pyramid ? 4 : 1, param->i_dpb_size));sps->i_num_ref_frames -= param->i_bframe_pyramid == X264_B_PYRAMID_STRICT;if( param->i_keyint_max == 1 ){sps->i_num_ref_frames = 0;sps->vui.i_max_dec_frame_buffering = 0;}/* number of refs + current frame */int max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!param->i_bframe_pyramid+1) + 1;/* Intra refresh cannot write a recovery time greater than max frame num-1 */if( param->b_intra_refresh ){int time_to_recovery = X264_MIN( sps->i_mb_width - 1, param->i_keyint_max ) + param->i_bframe - 1;max_frame_num = X264_MAX( max_frame_num, time_to_recovery+1 );}sps->i_log2_max_frame_num = 4;while( (1 << sps->i_log2_max_frame_num) <= max_frame_num )sps->i_log2_max_frame_num++;//POC类型sps->i_poc_type = param->i_bframe || param->b_interlaced || param->i_avcintra_class ? 0 : 2;if( sps->i_poc_type == 0 ){int max_delta_poc = (param->i_bframe + 2) * (!!param->i_bframe_pyramid + 1) * 2;sps->i_log2_max_poc_lsb = 4;while( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 )sps->i_log2_max_poc_lsb++;}sps->b_vui = 1;sps->b_gaps_in_frame_num_value_allowed = 0;sps->b_frame_mbs_only = !(param->b_interlaced || param->b_fake_interlaced);if( !sps->b_frame_mbs_only )sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1;sps->b_mb_adaptive_frame_field = param-&g


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部