void x264_sps_init( x264_sps_t *sps, int i_id, x264_param_t *param )
{
??? sps->i_id = i_id;首先設置序列參數集的ID
b_qpprime_y_zero_transform_bypass判斷碼率控制方法是否是恒定質量方法并且量化值初始為0.
??? sps->b_qpprime_y_zero_transform_bypass = param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0;
??? if( sps->b_qpprime_y_zero_transform_bypass )
??????? sps->i_profile_idc? = PROFILE_HIGH444_PREDICTIVE;
??? else if( param->analyse.b_transform_8x8 || param->i_cqm_preset != X264_CQM_FLAT )
??????? sps->i_profile_idc? = PROFILE_HIGH;
??? else if( param->b_cabac || param->i_bframe > 0 || param->b_interlaced )
??????? sps->i_profile_idc? = PROFILE_MAIN;
??? else
??????? sps->i_profile_idc? = PROFILE_BASELINE;
baseline:(1)b_qpprime_y_zero_transform_bypass不等于0(2)analyse.b_transform_8x8等于0并且param->i_cqm_preset = X264_CQM_FLAT(3)b_cabac等于0并且i_bframe小于等于0,并且interlaced=0
??? sps->i_level_idc = param->i_level_idc;
定義本序列參數集的level值
??? 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;?????? ?附錄A2.1
然后設置IDR幀之間的最大的幀數,這個幀數是以2的多少次冪計數的,它由參數的i_keyint_max(默認初始化為250)決定。
??? sps->i_log2_max_frame_num = 4;? /* at least 4這個句法元素是為讀取frame_num服務的 */
??? while( (1 << sps->i_log2_max_frame_num) <= param->i_keyint_max )
??? {
??????? sps->i_log2_max_frame_num++;
??? }
??? sps->i_log2_max_frame_num++;??? /* just in case */
然后設置i_poc_type為0,POC類型指明了POC的編碼方法,POC標識圖象的播放順序。由于H.264使用了B幀,使得圖象的解碼順序并不一定等于播放順序,但她們存在一定的映射關系。POC類型可以有Frame_num通過映射關系計算得來,也可以索性以編碼器顯示傳送的方式傳達給解碼器. POC類型有3種方案.
?? 然后設置i_log2_max_poc_lsb,最大POC的什么東西,也搞不明白。
?? POC是一個播放順序,接受到一個IDR偵,POC會被清0
??? sps->i_poc_type = 0;
??? if( sps->i_poc_type == 0 )此處不懂?
??? {
??????? sps->i_log2_max_poc_lsb = sps->i_log2_max_frame_num + 1;??? /* max poc = 2*frame_num */
??? }
??? else if( sps->i_poc_type == 1 )
??? {
?? ?????int i;
?
??????? /* FIXME */
??????? sps->b_delta_pic_order_always_zero = 1;
??????? sps->i_offset_for_non_ref_pic = 0;
??????? sps->i_offset_for_top_to_bottom_field = 0;
??????? sps->i_num_ref_frames_in_poc_cycle = 0;
?
??????? for( i = 0; i < sps->i_num_ref_frames_in_poc_cycle; i++ )
??????? {
??????????? sps->i_offset_for_ref_frame[i] = 0;
??????? }
??? }
??? sps->b_vui = 1; 指明vui子結構是否出現在碼流中(video usability information)
??? sps->b_gaps_in_frame_num_value_allowed = 0; 這個句法元素等于時,表示允許句法元素frame_num可以不連續;當傳輸信道堵塞時,允許丟棄若干幀
??? sps->i_mb_width = ( param->i_width + 15 ) / 16;
??? sps->i_mb_height= ( param->i_height + 15 ) / 16;
??? if( param->b_interlaced )
??????? sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1;
??? sps->b_frame_mbs_only = ! param->b_interlaced;
??? sps->b_mb_adaptive_frame_field = param->b_interlaced;
??? sps->b_direct8x8_inference = 1; 指明b片的直接和skip模式下運動矢量的預測方法
??? sps->crop.i_left?? = 0;
??? sps->crop.i_top??? = 0;
??? sps->crop.i_right? = sps->i_mb_width*16 - param->i_width;
??? sps->crop.i_bottom = (sps->i_mb_height*16 - param->i_height) >> param->b_interlaced;
??? sps->b_crop = sps->crop.i_left? || sps->crop.i_top ||
????????????????? sps->crop.i_right || sps->crop.i_bottom;
指明解碼器是否要將圖像裁剪后輸出,如果是的話,后面緊跟的四個句法元素分別指出左、右、上、下裁剪的寬度。此處不支持將圖像剪裁后輸出。
?
??? sps->vui.b_aspect_ratio_info_present = 0;是否有目前長寬比信息。?
??? if( param->vui.i_sar_width > 0 && param->vui.i_sar_height > 0 )
??? {
??????? sps->vui.b_aspect_ratio_info_present = 1;
?????? ?sps->vui.i_sar_width = param->vui.i_sar_width;
??????? sps->vui.i_sar_height= param->vui.i_sar_height;
??? }
?
??? sps->vui.b_overscan_info_present = ( param->vui.i_overscan ? 1 : 0 );i_overscan類型 0=undef, 1=no overscan, 2=overscan
??? if( sps->vui.b_overscan_info_present )
??????? sps->vui.b_overscan_info = ( param->vui.i_overscan == 2 ? 1 : 0 );
?
??? sps->vui.b_signal_type_present = 0;
??? sps->vui.i_vidformat = ( param->vui.i_vidformat <= 5 ? param->vui.i_vidformat : 5 );
??? sps->vui.b_fullrange = ( param->vui.b_fullrange ? 1 : 0 );
??? sps->vui.b_color_description_present = 0;
?
??? sps->vui.i_colorprim = ( param->vui.i_colorprim <=? 9 ? param->vui.i_colorprim : 2 ); /* undef原始色度格式*/
??? sps->vui.i_transfer? = ( param->vui.i_transfer? <= 11 ? param->vui.i_transfer? : 2 ); /* undef 轉換方式*/
??? sps->vui.i_colmatrix = ( param->vui.i_colmatrix <=? 9 ? param->vui.i_colmatrix : 2 ); /* undef 色度矩陣設置*/
??? if( sps->vui.i_colorprim != 2 ||
??????? sps->vui.i_transfer? != 2 ||
??????? sps->vui.i_colmatrix != 2 )
?? ?{
??????? sps->vui.b_color_description_present = 1;
??? }
?
??? if( sps->vui.i_vidformat != 5 ||
??????? sps->vui.b_fullrange ||
??????? sps->vui.b_color_description_present )
??? {
??????? sps->vui.b_signal_type_present = 1;
??? }
?
??? /* FIXME: not sufficient for interlaced video */解釋:對隔行掃描的視頻是沒有效。
??? sps->vui.b_chroma_loc_info_present = ( param->vui.i_chroma_loc ? 1 : 0 );
??? if( sps->vui.b_chroma_loc_info_present )判斷是否有當前色度樣本指定的信息。
??? {
??????? sps->vui.i_chroma_loc_top = param->vui.i_chroma_loc;
?? ?????sps->vui.i_chroma_loc_bottom = param->vui.i_chroma_loc;
??? }
?
??? sps->vui.b_timing_info_present = 0; 264碼流中時間相關信息是在vui中,x264生成的碼流是有vui信息的,但jm等編碼器默認情況下是不生成vui信息。這表示,其播放時間是不能給出的
??? if( param->i_fps_num > 0 && param->i_fps_den > 0)
??? {
??????? sps->vui.b_timing_info_present = 1;是否有目前的時間信息。
??????? sps->vui.i_num_units_in_tick = param->i_fps_den;在一個時間點的數量單位。
??????? sps->vui.i_time_scale = param->i_fps_num * 2;時間規模?
??????? sps->vui.b_fixed_frame_rate = 1;是否有恒定的幀率。/
??? }
?
??? sps->vui.i_num_reorder_frames = param->b_bframe_pyramid ? 2 : param->i_bframe ? 1 : 0; b_bframe_pyrami為允許部分B為參考幀。i_num_reorder_frames為重新排序的幀的數目。
??? /* extra slot with pyramid so that we don't have to override the
l??????? order of forgetting old pictures */
l??????? 額外的插入參考幀,以使得我們不用重寫忘記的老的圖像。
?? ?sps->vui.i_max_dec_frame_buffering =
??? sps->i_num_ref_frames = X264_MIN(16, X264_MAX(param->i_frame_reference, 1 + sps->vui.i_num_reorder_frames));
i_max_dec_frame_buffering最大的解碼幀的緩沖區。
??? sps->vui.b_bitstream_restriction = 1;是否比特流受限
??? if( sps->vui.b_bitstream_restriction )
??? {
??????? sps->vui.b_motion_vectors_over_pic_boundaries = 1; 是否有圖像邊界的運動矢量。
??????? sps->vui.i_max_bytes_per_pic_denom = 0; ?
??????? sps->vui.i_max_bits_per_mb_denom = 0;? ?
??????? sps->vui.i_log2_max_mv_length_horizontal =??? 宏塊水平長度的最大值。
??????? sps->vui.i_log2_max_mv_length_vertical =???? ?宏塊垂直長度的最大值。(int)(log(param->analyse.i_mv_range*4-1)/log(2)) + 1;
??? }
}