SubLayerHrdParameters HevcNalDecode::processSubLayerHrdParameters(uint8_t sub_pic_hrd_params_present_flag, std::size_t CpbCnt, BitstreamReader &bs) { SubLayerHrdParameters slhrd; slhrd.toDefault(); slhrd.bit_rate_value_minus1.resize(CpbCnt + 1); slhrd.cpb_size_value_minus1.resize(CpbCnt + 1); slhrd.cpb_size_du_value_minus1.resize(CpbCnt + 1); slhrd.bit_rate_du_value_minus1.resize(CpbCnt + 1); slhrd.cbr_flag.resize(CpbCnt + 1); for(std::size_t i=0; i<=CpbCnt; i++) { slhrd.bit_rate_value_minus1[i] = bs.getGolombU(); slhrd.cpb_size_value_minus1[i] = bs.getGolombU(); if(sub_pic_hrd_params_present_flag) { slhrd.cpb_size_du_value_minus1[i] = bs.getGolombU(); slhrd.bit_rate_du_value_minus1[i] = bs.getGolombU(); } slhrd.cbr_flag[i] = bs.getBits(1); } return slhrd; }
ScalingListData HevcNalDecode::processScalingListData(BitstreamReader &bs) { ScalingListData sc; sc.scaling_list_pred_mode_flag.resize(4); sc.scaling_list_pred_matrix_id_delta.resize(4); sc.scaling_list_dc_coef_minus8.resize(2); sc.scaling_list_delta_coef.resize(4); for(std::size_t sizeId = 0; sizeId < 4; sizeId++) { if(sizeId == 3) { sc.scaling_list_pred_mode_flag[sizeId].resize(2); sc.scaling_list_pred_matrix_id_delta[sizeId].resize(2); sc.scaling_list_dc_coef_minus8[sizeId-2].resize(2); sc.scaling_list_delta_coef[sizeId].resize(2); } else { sc.scaling_list_pred_mode_flag[sizeId].resize(6); sc.scaling_list_pred_matrix_id_delta[sizeId].resize(6); sc.scaling_list_delta_coef[sizeId].resize(6); if(sizeId >= 2) sc.scaling_list_dc_coef_minus8[sizeId-2].resize(6); } for(std::size_t matrixId = 0; matrixId<((sizeId == 3)?2:6); matrixId++) { sc.scaling_list_pred_mode_flag[sizeId][matrixId] = bs.getBits(1); if(!sc.scaling_list_pred_mode_flag[sizeId][matrixId]) sc.scaling_list_pred_matrix_id_delta[sizeId][matrixId] = bs.getGolombU(); else { std::size_t nextCoef = 8; std::size_t coefNum = std::min(64, (1 << (4 + (sizeId << 1)))); if(sizeId > 1) sc.scaling_list_dc_coef_minus8[sizeId-2][matrixId] = bs.getGolombS(); sc.scaling_list_delta_coef[sizeId][matrixId].resize(coefNum); for(std::size_t i = 0; i < coefNum; i++) sc.scaling_list_delta_coef[sizeId][matrixId][i] = bs.getGolombS(); } } } return sc; }
HrdParameters HevcNalDecode::processHrdParameters(uint8_t commonInfPresentFlag, std::size_t maxNumSubLayersMinus1, BitstreamReader &bs) { HrdParameters hrd; hrd.toDefault(); hrd.nal_hrd_parameters_present_flag = 0; hrd.vcl_hrd_parameters_present_flag = 0; hrd.sub_pic_hrd_params_present_flag = 0; hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = 0; if(commonInfPresentFlag) { hrd.nal_hrd_parameters_present_flag = bs.getBits(1); hrd.vcl_hrd_parameters_present_flag = bs.getBits(1); if(hrd.nal_hrd_parameters_present_flag || hrd.vcl_hrd_parameters_present_flag) { hrd.sub_pic_hrd_params_present_flag = bs.getBits(1); if(hrd.sub_pic_hrd_params_present_flag) { hrd.tick_divisor_minus2 = bs.getBits(8); hrd.du_cpb_removal_delay_increment_length_minus1 = bs.getBits(5); hrd.sub_pic_cpb_params_in_pic_timing_sei_flag = bs.getBits(1); hrd.dpb_output_delay_du_length_minus1 = bs.getBits(5); } hrd.bit_rate_scale = bs.getBits(4); hrd.cpb_size_scale = bs.getBits(4); if(hrd.sub_pic_hrd_params_present_flag) hrd.cpb_size_du_scale = bs.getBits(4); hrd.initial_cpb_removal_delay_length_minus1 = bs.getBits(5); hrd.au_cpb_removal_delay_length_minus1 = bs.getBits(5); hrd.dpb_output_delay_length_minus1 = bs.getBits(5); } } hrd.fixed_pic_rate_general_flag.resize(maxNumSubLayersMinus1 + 1); hrd.fixed_pic_rate_within_cvs_flag.resize(maxNumSubLayersMinus1 + 1); hrd.elemental_duration_in_tc_minus1.resize(maxNumSubLayersMinus1 + 1); hrd.low_delay_hrd_flag.resize(maxNumSubLayersMinus1 + 1, 0); hrd.cpb_cnt_minus1.resize(maxNumSubLayersMinus1 + 1, 0); if(hrd.nal_hrd_parameters_present_flag) hrd.nal_sub_layer_hrd_parameters.resize(maxNumSubLayersMinus1 + 1); if(hrd.vcl_hrd_parameters_present_flag) hrd.vcl_sub_layer_hrd_parameters.resize(maxNumSubLayersMinus1 + 1); for(std::size_t i = 0; i <= maxNumSubLayersMinus1; i++ ) { hrd.fixed_pic_rate_general_flag[i] = bs.getBits(1); if(hrd.fixed_pic_rate_general_flag[i]) hrd.fixed_pic_rate_within_cvs_flag[i] = 1; if(!hrd.fixed_pic_rate_general_flag[i]) hrd.fixed_pic_rate_within_cvs_flag[i] = bs.getBits(1); if(hrd.fixed_pic_rate_within_cvs_flag[i]) hrd.elemental_duration_in_tc_minus1[i] = bs.getGolombU(); else hrd.low_delay_hrd_flag[i] = bs.getBits(1); if(!hrd.low_delay_hrd_flag[i]) hrd.cpb_cnt_minus1[i] = bs.getGolombU(); if(hrd.nal_hrd_parameters_present_flag) hrd.nal_sub_layer_hrd_parameters[i] = processSubLayerHrdParameters(hrd.sub_pic_hrd_params_present_flag, hrd.cpb_cnt_minus1[i], bs); if(hrd.vcl_hrd_parameters_present_flag) hrd.vcl_sub_layer_hrd_parameters[i] = processSubLayerHrdParameters(hrd.sub_pic_hrd_params_present_flag, hrd.cpb_cnt_minus1[i], bs); } return hrd; }
ShortTermRefPicSet HevcNalDecode::processShortTermRefPicSet(std::size_t stRpsIdx, std::size_t num_short_term_ref_pic_sets, const std::vector<ShortTermRefPicSet> &refPicSets, std::shared_ptr<SPS> psps, BitstreamReader &bs) { ShortTermRefPicSet rpset; rpset.toDefault(); rpset.inter_ref_pic_set_prediction_flag = 0; rpset.delta_idx_minus1 = 0; if(stRpsIdx) { rpset.inter_ref_pic_set_prediction_flag = bs.getBits(1); } if(rpset.inter_ref_pic_set_prediction_flag) { if(stRpsIdx == num_short_term_ref_pic_sets) rpset.delta_idx_minus1 = bs.getGolombU(); rpset.delta_rps_sign = bs.getBits(1); rpset.abs_delta_rps_minus1 = bs.getGolombU(); std::size_t RefRpsIdx = stRpsIdx - (rpset.delta_idx_minus1 + 1); std::size_t NumDeltaPocs = 0; if(refPicSets[RefRpsIdx].inter_ref_pic_set_prediction_flag) { for(std::size_t i=0; i<refPicSets[RefRpsIdx].used_by_curr_pic_flag.size(); i++) if(refPicSets[RefRpsIdx].used_by_curr_pic_flag[i] || refPicSets[RefRpsIdx].use_delta_flag[i]) NumDeltaPocs++; } else NumDeltaPocs = refPicSets[RefRpsIdx].num_negative_pics + refPicSets[RefRpsIdx].num_positive_pics; rpset.used_by_curr_pic_flag.resize(NumDeltaPocs + 1); rpset.use_delta_flag.resize(NumDeltaPocs + 1, 1); for(std::size_t i=0; i<=NumDeltaPocs; i++ ) { rpset.used_by_curr_pic_flag[i] = bs.getBits(1); if(!rpset.used_by_curr_pic_flag[i]) rpset.use_delta_flag[i] = bs.getBits(1); } } else { rpset.num_negative_pics = bs.getGolombU(); rpset.num_positive_pics = bs.getGolombU(); if(rpset.num_negative_pics > psps -> sps_max_dec_pic_buffering_minus1[psps -> sps_max_sub_layers_minus1]) { LogDebug("HevcNalDecode:ShortTermRefPicSet: num_negative_pics > sps_max_dec_pic_buffering_minus1"); return rpset; } if(rpset.num_positive_pics > psps -> sps_max_dec_pic_buffering_minus1[psps -> sps_max_sub_layers_minus1]) { LogDebug("HevcNalDecode:ShortTermRefPicSet: num_positive_pics > sps_max_dec_pic_buffering_minus1"); return rpset; } rpset.delta_poc_s0_minus1.resize(rpset.num_negative_pics); rpset.used_by_curr_pic_s0_flag.resize(rpset.num_negative_pics); for(std::size_t i=0; i<rpset.num_negative_pics; i++) { rpset.delta_poc_s0_minus1[i] = bs.getGolombU(); rpset.used_by_curr_pic_s0_flag[i] = bs.getBits(1); } rpset.delta_poc_s1_minus1.resize(rpset.num_positive_pics); rpset.used_by_curr_pic_s1_flag.resize(rpset.num_positive_pics); for(std::size_t i=0; i<rpset.num_positive_pics; i++) { rpset.delta_poc_s1_minus1[i] = bs.getGolombU(); rpset.used_by_curr_pic_s1_flag[i] = bs.getBits(1); } } return rpset; }
VuiParameters HevcNalDecode::processVuiParameters(std::size_t sps_max_sub_layers_minus1, BitstreamReader &bs) { VuiParameters vui; vui.toDefault(); vui.aspect_ratio_idc = 0; vui.sar_width = 0; vui.sar_height = 0; vui.aspect_ratio_info_present_flag = bs.getBits(1); if(vui.aspect_ratio_info_present_flag) { vui.aspect_ratio_idc = bs.getBits(8); if(vui.aspect_ratio_idc == 255) //EXTENDED_SAR { vui.sar_width = bs.getBits(16); vui.sar_height = bs.getBits(16); } } vui.overscan_info_present_flag = bs.getBits(1); if(vui.overscan_info_present_flag) vui.overscan_appropriate_flag = bs.getBits(1); vui.video_format = 5; vui.video_full_range_flag = 0; vui.colour_primaries = 2; vui.transfer_characteristics = 2; vui.matrix_coeffs = 2; vui.video_signal_type_present_flag = bs.getBits(1); if(vui.video_signal_type_present_flag) { vui.video_format = bs.getBits(3); vui.video_full_range_flag = bs.getBits(1); vui.colour_description_present_flag = bs.getBits(1); if(vui.colour_description_present_flag) { vui.colour_primaries = bs.getBits(8); vui.transfer_characteristics = bs.getBits(8); vui.matrix_coeffs = bs.getBits(8); } } vui.chroma_sample_loc_type_top_field = 0; vui.chroma_sample_loc_type_bottom_field = 0; vui.chroma_loc_info_present_flag = bs.getBits(1); if(vui.chroma_loc_info_present_flag) { vui.chroma_sample_loc_type_top_field = bs.getGolombU(); vui.chroma_sample_loc_type_bottom_field = bs.getGolombU(); } vui.neutral_chroma_indication_flag = bs.getBits(1); vui.field_seq_flag = bs.getBits(1); vui.frame_field_info_present_flag = bs.getBits(1); vui.default_display_window_flag = bs.getBits(1); vui.def_disp_win_left_offset = 0; vui.def_disp_win_right_offset = 0; vui.def_disp_win_right_offset = 0; vui.def_disp_win_bottom_offset = 0; if(vui.default_display_window_flag) { vui.def_disp_win_left_offset = bs.getGolombU(); vui.def_disp_win_right_offset = bs.getGolombU(); vui.def_disp_win_top_offset = bs.getGolombU(); vui.def_disp_win_bottom_offset = bs.getGolombU(); } vui.vui_timing_info_present_flag = bs.getBits(1); if(vui.vui_timing_info_present_flag) { vui.vui_num_units_in_tick = bs.getBits(32); vui.vui_time_scale = bs.getBits(32); vui.vui_poc_proportional_to_timing_flag = bs.getBits(1); if(vui.vui_poc_proportional_to_timing_flag) vui.vui_num_ticks_poc_diff_one_minus1 = bs.getGolombU(); vui.vui_hrd_parameters_present_flag = bs.getBits(1); if(vui.vui_hrd_parameters_present_flag) vui.hrd_parameters = processHrdParameters(1, sps_max_sub_layers_minus1, bs); } vui.bitstream_restriction_flag = bs.getBits(1); if(vui.bitstream_restriction_flag) { vui.tiles_fixed_structure_flag = bs.getBits(1); vui.motion_vectors_over_pic_boundaries_flag = bs.getBits(1); vui.restricted_ref_pic_lists_flag = bs.getBits(1); vui.min_spatial_segmentation_idc = bs.getGolombU(); vui.max_bytes_per_pic_denom = bs.getGolombU(); vui.max_bits_per_min_cu_denom = bs.getGolombU(); vui.log2_max_mv_length_horizontal = bs.getGolombU(); vui.log2_max_mv_length_vertical = bs.getGolombU(); } return vui; }
void HevcNalDecode::processSPS(std::shared_ptr<SPS> psps, BitstreamReader &bs) { psps -> sps_video_parameter_set_id = bs.getBits(4); psps -> sps_max_sub_layers_minus1 = bs.getBits(3); psps -> sps_temporal_id_nesting_flag = bs.getBits(1); psps -> profile_tier_level = processProfileTierLevel(psps -> sps_max_sub_layers_minus1, bs); psps -> sps_seq_parameter_set_id = bs.getGolombU(); psps -> chroma_format_idc = bs.getGolombU(); if(psps -> chroma_format_idc == 3) psps -> separate_colour_plane_flag = bs.getBits(1); else psps -> separate_colour_plane_flag = 0; psps -> pic_width_in_luma_samples = bs.getGolombU(); psps -> pic_height_in_luma_samples = bs.getGolombU(); psps -> conformance_window_flag = bs.getBits(1); if(psps -> conformance_window_flag) { psps -> conf_win_left_offset = bs.getGolombU(); psps -> conf_win_right_offset = bs.getGolombU(); psps -> conf_win_top_offset = bs.getGolombU(); psps -> conf_win_bottom_offset = bs.getGolombU(); } psps -> bit_depth_luma_minus8 = bs.getGolombU(); psps -> bit_depth_chroma_minus8 = bs.getGolombU(); psps -> log2_max_pic_order_cnt_lsb_minus4 = bs.getGolombU(); psps -> sps_sub_layer_ordering_info_present_flag = bs.getBits(1); psps -> sps_max_dec_pic_buffering_minus1.resize(psps -> sps_max_sub_layers_minus1 + 1, 0); psps -> sps_max_num_reorder_pics.resize(psps -> sps_max_sub_layers_minus1 + 1, 0); psps -> sps_max_latency_increase_plus1.resize(psps -> sps_max_sub_layers_minus1 + 1, 0); for(std::size_t i=(psps -> sps_sub_layer_ordering_info_present_flag ? 0 : psps -> sps_max_sub_layers_minus1); i<=psps -> sps_max_sub_layers_minus1; i++) { psps -> sps_max_dec_pic_buffering_minus1[i] = bs.getGolombU(); psps -> sps_max_num_reorder_pics[i] = bs.getGolombU(); psps -> sps_max_latency_increase_plus1[i] = bs.getGolombU(); } psps -> log2_min_luma_coding_block_size_minus3 = bs.getGolombU(); psps -> log2_diff_max_min_luma_coding_block_size = bs.getGolombU(); psps -> log2_min_transform_block_size_minus2 = bs.getGolombU(); psps -> log2_diff_max_min_transform_block_size = bs.getGolombU(); psps -> max_transform_hierarchy_depth_inter = bs.getGolombU(); psps -> max_transform_hierarchy_depth_intra = bs.getGolombU(); psps -> scaling_list_enabled_flag = bs.getBits(1); if(psps -> scaling_list_enabled_flag) { psps -> sps_scaling_list_data_present_flag = bs.getBits(1); if(psps -> sps_scaling_list_data_present_flag) { psps -> scaling_list_data = processScalingListData(bs); } } psps -> amp_enabled_flag = bs.getBits(1); psps -> sample_adaptive_offset_enabled_flag = bs.getBits(1); psps -> pcm_enabled_flag = bs.getBits(1); if(psps -> pcm_enabled_flag) { psps -> pcm_sample_bit_depth_luma_minus1 = bs.getBits(4); psps -> pcm_sample_bit_depth_chroma_minus1 = bs.getBits(4); psps -> log2_min_pcm_luma_coding_block_size_minus3 = bs.getGolombU(); psps -> log2_diff_max_min_pcm_luma_coding_block_size = bs.getGolombU(); psps -> pcm_loop_filter_disabled_flag = bs.getBits(1); } psps -> num_short_term_ref_pic_sets = bs.getGolombU(); psps -> short_term_ref_pic_set.resize(psps -> num_short_term_ref_pic_sets); for(std::size_t i=0; i<psps -> num_short_term_ref_pic_sets; i++) psps -> short_term_ref_pic_set[i] = processShortTermRefPicSet(i, psps -> num_short_term_ref_pic_sets, psps -> short_term_ref_pic_set, psps, bs); psps -> long_term_ref_pics_present_flag = bs.getBits(1); if(psps -> long_term_ref_pics_present_flag) { psps -> num_long_term_ref_pics_sps = bs.getGolombU(); psps -> lt_ref_pic_poc_lsb_sps.resize(psps -> num_long_term_ref_pics_sps); psps -> used_by_curr_pic_lt_sps_flag.resize(psps -> num_long_term_ref_pics_sps); for(std::size_t i = 0; i<psps -> num_long_term_ref_pics_sps; i++) { psps -> lt_ref_pic_poc_lsb_sps[i] = bs.getBits(psps -> log2_max_pic_order_cnt_lsb_minus4 + 4); psps -> used_by_curr_pic_lt_sps_flag[i] = bs.getBits(1); } } psps -> sps_temporal_mvp_enabled_flag = bs.getBits(1); psps -> strong_intra_smoothing_enabled_flag = bs.getBits(1); psps -> vui_parameters_present_flag = bs.getBits(1); if(psps -> vui_parameters_present_flag) { psps -> vui_parameters = processVuiParameters(psps -> sps_max_sub_layers_minus1, bs); } psps -> sps_extension_flag = bs.getBits(1); }