static bool hevc_parse_scaling_list_rbsp( bs_t *p_bs ) { if( bs_remain( p_bs ) < 16 ) return false; for( int i=0; i<4; i++ ) { for( int j=0; j<6; j += (i == 3) ? 3 : 1 ) { if( bs_read1( p_bs ) == 0 ) bs_read_ue( p_bs ); else { unsigned nextCoef = 8; unsigned coefNum = __MIN( 64, (1 << (4 + (i << 1)))); if( i > 1 ) { nextCoef = bs_read_se( p_bs ) + 8; } for( unsigned k=0; k<coefNum; k++ ) { nextCoef = ( nextCoef + bs_read_se( p_bs ) + 256 ) % 256; } } } } return true; }
static bool hevc_parse_profile_tier_level_rbsp( bs_t *p_bs, bool profile_present, uint8_t max_num_sub_layers_minus1, hevc_profile_tier_level_t *p_ptl ) { if( profile_present && !hevc_parse_inner_profile_tier_level_rbsp( p_bs, &p_ptl->general ) ) return false; if( bs_remain( p_bs ) < 8) return false; p_ptl->general_level_idc = bs_read( p_bs, 8 ); if( max_num_sub_layers_minus1 > 0 ) { if( bs_remain( p_bs ) < 16 ) return false; for( uint8_t i=0; i< 8; i++ ) { if( i < max_num_sub_layers_minus1 ) { if( bs_read1( p_bs ) ) p_ptl->sublayer_profile_present_flag |= (0x80 >> i); if( bs_read1( p_bs ) ) p_ptl->sublayer_level_present_flag |= (0x80 >> i); } else bs_read( p_bs, 2 ); } for( uint8_t i=0; i < max_num_sub_layers_minus1; i++ ) { if( ( p_ptl->sublayer_profile_present_flag & (0x80 >> i) ) && ! hevc_parse_inner_profile_tier_level_rbsp( p_bs, &p_ptl->sub_layer[i] ) ) return false; if( p_ptl->sublayer_profile_present_flag & (0x80 >> i) ) { if( bs_remain( p_bs ) < 8 ) return false; p_ptl->sub_layer_level_idc[i] = bs_read( p_bs, 8 ); } } }
static bool hevc_parse_inner_profile_tier_level_rbsp( bs_t *p_bs, hevc_inner_profile_tier_level_t *p_in ) { if( bs_remain( p_bs ) < 88 ) return false; p_in->profile_space = bs_read( p_bs, 2 ); p_in->tier_flag = bs_read1( p_bs ); p_in->profile_idc = bs_read( p_bs, 5 ); p_in->profile_compatibility_flag = bs_read( p_bs, 32 ); p_in->progressive_source_flag = bs_read1( p_bs ); p_in->interlaced_source_flag = bs_read1( p_bs ); p_in->non_packed_constraint_flag = bs_read1( p_bs ); p_in->frame_only_constraint_flag = bs_read1( p_bs ); if( ( p_in->profile_idc >= 4 && p_in->profile_idc <= 7 ) || ( p_in->profile_compatibility_flag & 0x0F000000 ) ) { p_in->idc4to7.max_12bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_10bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_8bit_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_422chroma_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_420chroma_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.max_monochrome_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.intra_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.one_picture_only_constraint_flag = bs_read1( p_bs ); p_in->idc4to7.lower_bit_rate_constraint_flag = bs_read1( p_bs ); (void) bs_read( p_bs, 2 ); } else { (void) bs_read( p_bs, 11 ); } (void) bs_read( p_bs, 32 ); if( ( p_in->profile_idc >= 1 && p_in->profile_idc <= 5 ) || ( p_in->profile_compatibility_flag & 0x7C000000 ) ) p_in->idc1to5.inbld_flag = bs_read1( p_bs ); else (void) bs_read1( p_bs ); return true; }
static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs, h264_sequence_parameter_set_t *p_sps ) { int i_tmp; int i_profile_idc = bs_read( p_bs, 8 ); p_sps->i_profile = i_profile_idc; p_sps->i_constraint_set_flags = bs_read( p_bs, 8 ); p_sps->i_level = bs_read( p_bs, 8 ); /* sps id */ uint32_t i_sps_id = bs_read_ue( p_bs ); if( i_sps_id > H264_SPS_ID_MAX ) return false; p_sps->i_id = i_sps_id; if( i_profile_idc == PROFILE_H264_HIGH || i_profile_idc == PROFILE_H264_HIGH_10 || i_profile_idc == PROFILE_H264_HIGH_422 || i_profile_idc == PROFILE_H264_HIGH_444 || /* Old one, no longer on spec */ i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE || i_profile_idc == PROFILE_H264_CAVLC_INTRA || i_profile_idc == PROFILE_H264_SVC_BASELINE || i_profile_idc == PROFILE_H264_SVC_HIGH || i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_HIGH || i_profile_idc == PROFILE_H264_MVC_STEREO_HIGH || i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_DEPTH_HIGH || i_profile_idc == PROFILE_H264_MVC_ENHANCED_MULTIVIEW_DEPTH_HIGH || i_profile_idc == PROFILE_H264_MFC_HIGH ) { /* chroma_format_idc */ p_sps->i_chroma_idc = bs_read_ue( p_bs ); if( p_sps->i_chroma_idc == 3 ) bs_skip( p_bs, 1 ); /* separate_colour_plane_flag */ /* bit_depth_luma_minus8 */ p_sps->i_bit_depth_luma = bs_read_ue( p_bs ) + 8; /* bit_depth_chroma_minus8 */ p_sps->i_bit_depth_chroma = bs_read_ue( p_bs ) + 8; /* qpprime_y_zero_transform_bypass_flag */ bs_skip( p_bs, 1 ); /* seq_scaling_matrix_present_flag */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { for( int i = 0; i < ((3 != p_sps->i_chroma_idc) ? 8 : 12); i++ ) { /* seq_scaling_list_present_flag[i] */ i_tmp = bs_read( p_bs, 1 ); if( !i_tmp ) continue; const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64; /* scaling_list (...) */ int i_lastscale = 8; int i_nextscale = 8; for( int j = 0; j < i_size_of_scaling_list; j++ ) { if( i_nextscale != 0 ) { /* delta_scale */ i_tmp = bs_read_se( p_bs ); i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256; /* useDefaultScalingMatrixFlag = ... */ } /* scalinglist[j] */ i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale; } } } } /* Skip i_log2_max_frame_num */ p_sps->i_log2_max_frame_num = bs_read_ue( p_bs ); if( p_sps->i_log2_max_frame_num > 12) p_sps->i_log2_max_frame_num = 12; /* Read poc_type */ p_sps->i_pic_order_cnt_type = bs_read_ue( p_bs ); if( p_sps->i_pic_order_cnt_type == 0 ) { /* skip i_log2_max_poc_lsb */ p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( p_bs ); if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 ) p_sps->i_log2_max_pic_order_cnt_lsb = 12; } else if( p_sps->i_pic_order_cnt_type == 1 ) { int i_cycle; /* skip b_delta_pic_order_always_zero */ p_sps->i_delta_pic_order_always_zero_flag = bs_read( p_bs, 1 ); /* skip i_offset_for_non_ref_pic */ bs_read_se( p_bs ); /* skip i_offset_for_top_to_bottom_field */ bs_read_se( p_bs ); /* read i_num_ref_frames_in_poc_cycle */ i_cycle = bs_read_ue( p_bs ); if( i_cycle > 256 ) i_cycle = 256; while( i_cycle > 0 ) { /* skip i_offset_for_ref_frame */ bs_read_se(p_bs ); i_cycle--; } } /* i_num_ref_frames */ bs_read_ue( p_bs ); /* b_gaps_in_frame_num_value_allowed */ bs_skip( p_bs, 1 ); /* Read size */ p_sps->pic_width_in_mbs_minus1 = bs_read_ue( p_bs ); p_sps->pic_height_in_map_units_minus1 = bs_read_ue( p_bs ); /* b_frame_mbs_only */ p_sps->frame_mbs_only_flag = bs_read( p_bs, 1 ); if( !p_sps->frame_mbs_only_flag ) bs_skip( p_bs, 1 ); /* b_direct8x8_inference */ bs_skip( p_bs, 1 ); /* crop */ if( bs_read1( p_bs ) ) /* frame_cropping_flag */ { p_sps->frame_crop.left_offset = bs_read_ue( p_bs ); p_sps->frame_crop.right_offset = bs_read_ue( p_bs ); p_sps->frame_crop.right_offset = bs_read_ue( p_bs ); p_sps->frame_crop.bottom_offset = bs_read_ue( p_bs ); } /* vui */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { p_sps->vui.b_valid = true; /* read the aspect ratio part if any */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { static const struct { int w, h; } sar[17] = { { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 }, { 160,99 }, { 4, 3 }, { 3, 2 }, { 2, 1 }, }; int i_sar = bs_read( p_bs, 8 ); int w, h; if( i_sar < 17 ) { w = sar[i_sar].w; h = sar[i_sar].h; } else if( i_sar == 255 ) { w = bs_read( p_bs, 16 ); h = bs_read( p_bs, 16 ); } else { w = 0; h = 0; } if( w != 0 && h != 0 ) { p_sps->vui.i_sar_num = w; p_sps->vui.i_sar_den = h; } else { p_sps->vui.i_sar_num = 1; p_sps->vui.i_sar_den = 1; } } /* overscan */ i_tmp = bs_read( p_bs, 1 ); if ( i_tmp ) bs_read( p_bs, 1 ); /* video signal type */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { bs_read( p_bs, 3 ); p_sps->vui.colour.b_full_range = bs_read( p_bs, 1 ); /* colour desc */ i_tmp = bs_read( p_bs, 1 ); if ( i_tmp ) { p_sps->vui.colour.i_colour_primaries = bs_read( p_bs, 8 ); p_sps->vui.colour.i_transfer_characteristics = bs_read( p_bs, 8 ); p_sps->vui.colour.i_matrix_coefficients = bs_read( p_bs, 8 ); } else { p_sps->vui.colour.i_colour_primaries = HXXX_PRIMARIES_UNSPECIFIED; p_sps->vui.colour.i_transfer_characteristics = HXXX_TRANSFER_UNSPECIFIED; p_sps->vui.colour.i_matrix_coefficients = HXXX_MATRIX_UNSPECIFIED; } } /* chroma loc info */ i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { bs_read_ue( p_bs ); bs_read_ue( p_bs ); } /* timing info */ p_sps->vui.b_timing_info_present_flag = bs_read( p_bs, 1 ); if( p_sps->vui.b_timing_info_present_flag ) { p_sps->vui.i_num_units_in_tick = bs_read( p_bs, 32 ); p_sps->vui.i_time_scale = bs_read( p_bs, 32 ); p_sps->vui.b_fixed_frame_rate = bs_read( p_bs, 1 ); } /* Nal hrd & VC1 hrd parameters */ p_sps->vui.b_hrd_parameters_present_flag = false; for ( int i=0; i<2; i++ ) { i_tmp = bs_read( p_bs, 1 ); if( i_tmp ) { p_sps->vui.b_hrd_parameters_present_flag = true; uint32_t count = bs_read_ue( p_bs ) + 1; if( count > 31 ) return false; bs_read( p_bs, 4 ); bs_read( p_bs, 4 ); for( uint32_t i=0; i<count; i++ ) { if( bs_remain( p_bs ) < 23 ) return false; bs_read_ue( p_bs ); bs_read_ue( p_bs ); bs_read( p_bs, 1 ); } bs_read( p_bs, 5 ); p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( p_bs, 5 ); p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( p_bs, 5 ); bs_read( p_bs, 5 ); } } if( p_sps->vui.b_hrd_parameters_present_flag ) bs_read( p_bs, 1 ); /* pic struct info */ p_sps->vui.b_pic_struct_present_flag = bs_read( p_bs, 1 ); /* + unparsed remains */ } return true; }
static bool hevc_parse_vui_parameters_rbsp( bs_t *p_bs, hevc_vui_parameters_t *p_vui ) { if( bs_remain( p_bs ) < 10 ) return false; p_vui->aspect_ratio_info_present_flag = bs_read1( p_bs ); if( p_vui->aspect_ratio_info_present_flag ) { p_vui->ar.aspect_ratio_idc = bs_read( p_bs, 8 ); if( p_vui->ar.aspect_ratio_idc == 0xFF ) //HEVC_SAR__IDC_EXTENDED_SAR ) { p_vui->ar.sar_width = bs_read( p_bs, 16 ); p_vui->ar.sar_height = bs_read( p_bs, 16 ); } } p_vui->overscan_info_present_flag = bs_read1( p_bs ); if( p_vui->overscan_info_present_flag ) p_vui->overscan_appropriate_flag = bs_read1( p_bs ); p_vui->video_signal_type_present_flag = bs_read1( p_bs ); if( p_vui->video_signal_type_present_flag ) { p_vui->vs.video_format = bs_read( p_bs, 3 ); p_vui->vs.video_full_range_flag = bs_read1( p_bs ); p_vui->vs.colour_description_present_flag = bs_read1( p_bs ); if( p_vui->vs.colour_description_present_flag ) { p_vui->vs.colour.colour_primaries = bs_read( p_bs, 8 ); p_vui->vs.colour.transfer_characteristics = bs_read( p_bs, 8 ); p_vui->vs.colour.matrix_coeffs = bs_read( p_bs, 8 ); } } p_vui->chroma_loc_info_present_flag = bs_read1( p_bs ); if( p_vui->chroma_loc_info_present_flag ) { p_vui->chroma.sample_loc_type_top_field = bs_read_ue( p_bs ); p_vui->chroma.sample_loc_type_bottom_field = bs_read_ue( p_bs ); } p_vui->neutral_chroma_indication_flag = bs_read1( p_bs ); p_vui->field_seq_flag = bs_read1( p_bs ); p_vui->frame_field_info_present_flag = bs_read1( p_bs ); p_vui->default_display_window_flag = bs_read1( p_bs ); if( p_vui->default_display_window_flag ) { p_vui->def_disp.win_left_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_right_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_top_offset = bs_read_ue( p_bs ); p_vui->def_disp.win_bottom_offset = bs_read_ue( p_bs ); } p_vui->vui_timing_info_present_flag = bs_read1( p_bs ); if( p_vui->vui_timing_info_present_flag ) { p_vui->timing.vui_num_units_in_tick = bs_read( p_bs, 32 ); p_vui->timing.vui_time_scale = bs_read( p_bs, 32 ); if( bs_remain( p_bs ) < 3 ) return false; } /* incomplete */ if( bs_remain( p_bs ) < 1 ) /* late fail */ return false; return true; }