From 298d8e3a8fe0d6c500d0c006bceebd4defcf1f06 Mon Sep 17 00:00:00 2001 From: jeffqjiangNew <142832361+jeffqjiangNew@users.noreply.github.com> Date: Thu, 26 Oct 2023 11:38:46 -0400 Subject: [PATCH] Added full parsing of the slice segment header. (#26) * rocDecode/HEVC parsing: Implemented correct logic to set active VPS, SPS and PPS: start from slice header and up. Added video image size change detection. Fixed slice_segment_address bits calculation in slice segment header parsing. * rocDecode/HEVC: Changed variable naming to Google style. * rocDecode/HEVC: Added VPS, SPS, PPS, and slice segment header content logging functions for debug purposes. * rocDecode/HEVC: Compacted opening bracket lines to keep coding style consistency. * * rocDecode/HEVC: Fixed an issue in profile-tier-level parsing where 44 bits are skipped in an incorrect way using ReadBits() which can only consume 32 bits max. Also formated SPS parsing code by using pointer instead of array element. * * rocDecode/HEVC: Fixed the incorrect array size for sps_max_dec_pic_buffering_minus1, sps_max_num_reorder_pics and sps_max_num_reorder_pics in SPS structure define. * * rocDecode/HEVC: Modified scaling list parsing to make sure we explicitly follow the spec. * * rocDecode/HEVC: Added a few syntax elements to short team RPS structure, updated RPS parsing function and logging function. * * rocDecode/HEVC: In PPS parsing function, use structure pointer instead of structure array element to improve coding clarity. * * rocDecode/HEVC: Compacted the opening bracket lines. No functional changes. * * rocDecode/HEVC: Added full parsing of slice segment header. Added PPS range extension parsing. * * rocDecode/HEVC: Fixed a build error in debug mode due to merging from master branch: removing a redundant debug function. --- src/parser/hevc_parser.cpp | 286 +++++++++++++++++++++++++++++++++---- src/parser/hevc_parser.h | 60 +++++++- 2 files changed, 316 insertions(+), 30 deletions(-) diff --git a/src/parser/hevc_parser.cpp b/src/parser/hevc_parser.cpp index 035d04307d..fe3a222112 100644 --- a/src/parser/hevc_parser.cpp +++ b/src/parser/hevc_parser.cpp @@ -639,6 +639,59 @@ void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_ } } +void HEVCVideoParser::ParsePredWeightTable(HEVCVideoParser::SliceHeaderData *slice_header_ptr, int chroma_array_type, uint8_t *stream_ptr, size_t &offset) { + HevcPredWeightTable *pred_weight_table_ptr = &slice_header_ptr->pred_weight_table; + int i, j; + + pred_weight_table_ptr->luma_log2_weight_denom = Parser::ExpGolomb::ReadUe(stream_ptr, offset); + if (chroma_array_type) { + pred_weight_table_ptr->delta_chroma_log2_weight_denom = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + } + for (i = 0; i <= slice_header_ptr->num_ref_idx_l0_active_minus1; i++) { + pred_weight_table_ptr->luma_weight_l0_flag[i] = Parser::GetBit(stream_ptr, offset); + } + if (chroma_array_type) { + for (i = 0; i <= slice_header_ptr->num_ref_idx_l0_active_minus1; i++) { + pred_weight_table_ptr->chroma_weight_l0_flag[i] = Parser::GetBit(stream_ptr, offset); + } + } + for (i = 0; i <= slice_header_ptr->num_ref_idx_l0_active_minus1; i++) { + if (pred_weight_table_ptr->luma_weight_l0_flag[i]) { + pred_weight_table_ptr->delta_luma_weight_l0[i] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + pred_weight_table_ptr->luma_offset_l0[i] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + } + if (pred_weight_table_ptr->chroma_weight_l0_flag[i]) { + for (j = 0; j < 2; j++) { + pred_weight_table_ptr->delta_chroma_weight_l0[i][j] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + pred_weight_table_ptr->delta_chroma_offset_l0[i][j] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + } + } + } + + if (slice_header_ptr->slice_type == HEVC_SLICE_TYPE_B) { + for (i = 0; i <= slice_header_ptr->num_ref_idx_l1_active_minus1; i++) { + pred_weight_table_ptr->luma_weight_l1_flag[i] = Parser::GetBit(stream_ptr, offset); + } + if (chroma_array_type) { + for (i = 0; i <= slice_header_ptr->num_ref_idx_l1_active_minus1; i++) { + pred_weight_table_ptr->chroma_weight_l1_flag[i] = Parser::GetBit(stream_ptr, offset); + } + } + for (i = 0; i <= slice_header_ptr->num_ref_idx_l1_active_minus1; i++) { + if (pred_weight_table_ptr->luma_weight_l1_flag[i]) { + pred_weight_table_ptr->delta_luma_weight_l1[i] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + pred_weight_table_ptr->luma_offset_l1[i] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + } + if (pred_weight_table_ptr->chroma_weight_l1_flag[i]) { + for (j = 0; j < 2; j++) { + pred_weight_table_ptr->delta_chroma_weight_l1[i][j] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + pred_weight_table_ptr->delta_chroma_offset_l1[i][j] = Parser::ExpGolomb::ReadSe(stream_ptr, offset); + } + } + } + } +} + void HEVCVideoParser::ParseVui(H265VuiParameters *vui, uint32_t max_num_sub_layers_minus1, uint8_t *nalu, size_t size, size_t &offset) { vui->aspect_ratio_info_present_flag = Parser::GetBit(nalu, offset); if (vui->aspect_ratio_info_present_flag) { @@ -954,7 +1007,31 @@ void HEVCVideoParser::ParsePps(uint8_t *nalu, size_t size) { pps_ptr->lists_modification_present_flag = Parser::GetBit(nalu, offset); pps_ptr->log2_parallel_merge_level_minus2 = Parser::ExpGolomb::ReadUe(nalu, offset); pps_ptr->slice_segment_header_extension_present_flag = Parser::GetBit(nalu, offset); - pps_ptr->pps_extension_flag = Parser::GetBit(nalu, offset); + pps_ptr->pps_extension_present_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->pps_extension_present_flag) { + pps_ptr->pps_range_extension_flag = Parser::GetBit(nalu, offset); + pps_ptr->pps_multilayer_extension_flag = Parser::GetBit(nalu, offset); + pps_ptr->pps_extension_6bits = Parser::ReadBits(nalu, offset, 6); + } + + // pps_range_extension() + if (pps_ptr->pps_range_extension_flag) { + if (pps_ptr->transform_skip_enabled_flag) { + pps_ptr->log2_max_transform_skip_block_size_minus2 = Parser::ExpGolomb::ReadUe(nalu, offset); + } + pps_ptr->cross_component_prediction_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->chroma_qp_offset_list_enabled_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->chroma_qp_offset_list_enabled_flag) { + pps_ptr->diff_cu_chroma_qp_offset_depth = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->chroma_qp_offset_list_len_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + for (int i = 0; i <= pps_ptr->chroma_qp_offset_list_len_minus1; i++) { + pps_ptr->cb_qp_offset_list[i] = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->cr_qp_offset_list[i] = Parser::ExpGolomb::ReadSe(nalu, offset); + } + } + pps_ptr->log2_sao_offset_scale_luma = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->log2_sao_offset_scale_chroma = Parser::ExpGolomb::ReadUe(nalu, offset); + } #if DBGINFO PrintPps(pps_ptr); @@ -966,6 +1043,7 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si SpsData *sps_ptr = NULL; size_t offset = 0; SliceHeaderData temp_sh; + memset(m_sh_, 0, sizeof(SliceHeaderData)); memset(&temp_sh, 0, sizeof(temp_sh)); temp_sh.first_slice_segment_in_pic_flag = m_sh_->first_slice_segment_in_pic_flag = Parser::GetBit(nalu, offset); @@ -1065,6 +1143,9 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si if (num_bits > 0) { m_sh_->short_term_ref_pic_set_idx = Parser::ReadBits(nalu, offset, num_bits); } + + // Copy the SPS RPS to slice RPS + m_sh_->st_rps = sps_ptr->st_rps[m_sh_->short_term_ref_pic_set_idx]; } m_sh_->short_term_ref_pic_set_size = offset - pos; @@ -1084,16 +1165,16 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si if (sps_ptr->num_long_term_ref_pics_sps > 1) { if( bits_for_ltrp_in_sps > 0) { m_sh_->lt_idx_sps[i] = Parser::ReadBits(nalu, offset, bits_for_ltrp_in_sps); - m_sh_->lt_rps.pocs[i] = sps_ptr->lt_rps.pocs[m_sh_->lt_idx_sps[i]]; - m_sh_->lt_rps.used_by_curr_pic[i] = sps_ptr->lt_rps.used_by_curr_pic[m_sh_->lt_idx_sps[i]]; + m_sh_->lt_rps.pocs[i] = sps_ptr->lt_rps.pocs[m_sh_->lt_idx_sps[i]]; // PocLsbLt[] + m_sh_->lt_rps.used_by_curr_pic[i] = sps_ptr->lt_rps.used_by_curr_pic[m_sh_->lt_idx_sps[i]]; // UsedByCurrPicLt[] } } } else { m_sh_->poc_lsb_lt[i] = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4)); m_sh_->used_by_curr_pic_lt_flag[i] = Parser::GetBit(nalu, offset); - m_sh_->lt_rps.pocs[i] = m_sh_->poc_lsb_lt[i]; - m_sh_->lt_rps.used_by_curr_pic[i] = m_sh_->used_by_curr_pic_lt_flag[i]; + m_sh_->lt_rps.pocs[i] = m_sh_->poc_lsb_lt[i]; // PocLsbLt[] + m_sh_->lt_rps.used_by_curr_pic[i] = m_sh_->used_by_curr_pic_lt_flag[i]; // UsedByCurrPicLt[] } m_sh_->delta_poc_msb_present_flag[i] = Parser::GetBit(nalu, offset); if (m_sh_->delta_poc_msb_present_flag[i]) { @@ -1105,6 +1186,120 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si m_sh_->slice_temporal_mvp_enabled_flag = Parser::GetBit(nalu, offset); } } + + int chroma_array_type = sps_ptr->separate_colour_plane_flag ? 0 : sps_ptr->chroma_format_idc; // ChromaArrayType + if (sps_ptr->sample_adaptive_offset_enabled_flag) { + m_sh_->slice_sao_luma_flag = Parser::GetBit(nalu, offset); + if (chroma_array_type) + { + m_sh_->slice_sao_chroma_flag = Parser::GetBit(nalu, offset); + } + } + + if (m_sh_->slice_type == HEVC_SLICE_TYPE_P || m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->num_ref_idx_active_override_flag = Parser::GetBit(nalu, offset); + if (m_sh_->num_ref_idx_active_override_flag) { + m_sh_->num_ref_idx_l0_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->num_ref_idx_l1_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + } + } + else { + m_sh_->num_ref_idx_l0_active_minus1 = pps_ptr->num_ref_idx_l0_default_active_minus1; + if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->num_ref_idx_l1_active_minus1 = pps_ptr->num_ref_idx_l1_default_active_minus1; + } + } + + // 7.3.6.2 Reference picture list modification + // Calculate NumPicTotalCurr + int num_pic_total_curr = 0; + H265ShortTermRPS *st_rps_ptr = &m_sh_->st_rps; + // Check the combined list + for (int i = 0; i < st_rps_ptr->num_of_delta_poc; i++) { + if (st_rps_ptr->used_by_curr_pic[i]) { + num_pic_total_curr++; + } + } + + H265LongTermRPS *lt_rps_ptr = &m_sh_->lt_rps; + // Check the combined list + for (int i = 0; i < lt_rps_ptr->num_of_pics; i++) { + if (lt_rps_ptr->used_by_curr_pic[i]) { + num_pic_total_curr++; + } + } + + if (pps_ptr->lists_modification_present_flag && num_pic_total_curr > 1) + { + int list_entry_bits = 0; + while ((1 << list_entry_bits) < num_pic_total_curr) { + list_entry_bits++; + } + + m_sh_->ref_pic_list_modification_flag_l0 = Parser::GetBit(nalu, offset); + if (m_sh_->ref_pic_list_modification_flag_l0) { + for (int i = 0; i < m_sh_->num_ref_idx_l0_active_minus1; i++) { + m_sh_->list_entry_l0[i] = Parser::ReadBits(nalu, offset, list_entry_bits); + } + } + + if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->ref_pic_list_modification_flag_l1 = Parser::GetBit(nalu, offset); + if (m_sh_->ref_pic_list_modification_flag_l1) { + for (int i = 0; i < m_sh_->num_ref_idx_l1_active_minus1; i++) { + m_sh_->list_entry_l1[i] = Parser::ReadBits(nalu, offset, list_entry_bits); + } + } + } + } + + if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->mvd_l1_zero_flag = Parser::GetBit(nalu, offset); + } + if (pps_ptr->cabac_init_present_flag) { + m_sh_->cabac_init_flag = Parser::GetBit(nalu, offset); + } + + if (m_sh_->slice_temporal_mvp_enabled_flag) { + if (m_sh_->slice_type == HEVC_SLICE_TYPE_B) { + m_sh_->collocated_from_l0_flag = Parser::GetBit(nalu, offset); + } + if ((m_sh_->collocated_from_l0_flag && m_sh_->num_ref_idx_l0_active_minus1 > 0) || (!m_sh_->collocated_from_l0_flag && m_sh_->num_ref_idx_l1_active_minus1 > 0)) { + m_sh_->collocated_ref_idx = Parser::ExpGolomb::ReadUe(nalu, offset); + } + } + + if ((pps_ptr->weighted_pred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_P) || (pps_ptr->weighted_bipred_flag && m_sh_->slice_type == HEVC_SLICE_TYPE_B)) { + ParsePredWeightTable(m_sh_, chroma_array_type, nalu, offset); + } + m_sh_->five_minus_max_num_merge_cand = Parser::ExpGolomb::ReadUe(nalu, offset); + } + + m_sh_->slice_qp_delta = Parser::ExpGolomb::ReadSe(nalu, offset); + if (pps_ptr->pps_slice_chroma_qp_offsets_present_flag) { + m_sh_->slice_cb_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); + m_sh_->slice_cr_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); + } + if (pps_ptr->chroma_qp_offset_list_enabled_flag) { + m_sh_->cu_chroma_qp_offset_enabled_flag = Parser::GetBit(nalu, offset); + } + if (pps_ptr->deblocking_filter_override_enabled_flag) { + m_sh_->deblocking_filter_override_flag = Parser::GetBit(nalu, offset); + } + if (m_sh_->deblocking_filter_override_flag) { + m_sh_->slice_deblocking_filter_disabled_flag = Parser::GetBit(nalu, offset); + if ( !m_sh_->slice_deblocking_filter_disabled_flag ) { + m_sh_->slice_beta_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); + m_sh_->slice_tc_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); + } + } + + if (pps_ptr->pps_loop_filter_across_slices_enabled_flag && (m_sh_->slice_sao_luma_flag || m_sh_->slice_sao_chroma_flag || +!m_sh_->slice_deblocking_filter_disabled_flag)) { + m_sh_->slice_loop_filter_across_slices_enabled_flag = Parser::GetBit(nalu, offset); + } + memcpy(m_sh_copy_, m_sh_, sizeof(*m_sh_)); } else { @@ -1117,6 +1312,23 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si m_sh_->slice_segment_address = temp_sh.slice_segment_address; } + if (pps_ptr->tiles_enabled_flag || pps_ptr->entropy_coding_sync_enabled_flag) { + m_sh_->num_entry_point_offsets = Parser::ExpGolomb::ReadUe(nalu, offset); + if (m_sh_->num_entry_point_offsets) { + m_sh_->offset_len_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + for (int i = 0; i < m_sh_->num_entry_point_offsets; i++) { + m_sh_->entry_point_offset_minus1[i] = Parser::ReadBits(nalu, offset, m_sh_->offset_len_minus1 + 1); + } + } + } + + if (pps_ptr->slice_segment_header_extension_present_flag) { + m_sh_->slice_segment_header_extension_length = Parser::ExpGolomb::ReadUe(nalu, offset); + for (int i = 0; i < m_sh_->slice_segment_header_extension_length; i++) { + m_sh_->slice_segment_header_extension_data_byte[i] = Parser::ReadBits(nalu, offset, 8); + } + } + #if DBGINFO PrintSliceSegHeader(m_sh_); #endif // DBGINFO @@ -1300,7 +1512,7 @@ void HEVCVideoParser::PrintSps(HEVCVideoParser::SpsData *sps_ptr) { if (sps_ptr->num_short_term_ref_pic_sets) { for(int i = 0; i < sps_ptr->num_short_term_ref_pic_sets; i++) { - PrintRps(&sps_ptr->st_rps[i]); + PrintStRps(&sps_ptr->st_rps[i]); } } @@ -1320,6 +1532,8 @@ void HEVCVideoParser::PrintSps(HEVCVideoParser::SpsData *sps_ptr) { MSG(""); } + PrintLtRefInfo(&sps_ptr->lt_rps); + MSG("sps_temporal_mvp_enabled_flag = " << sps_ptr->sps_temporal_mvp_enabled_flag); MSG("strong_intra_smoothing_enabled_flag = " << sps_ptr->strong_intra_smoothing_enabled_flag); MSG("vui_parameters_present_flag = " << sps_ptr->vui_parameters_present_flag); @@ -1389,7 +1603,7 @@ void HEVCVideoParser::PrintPps(HEVCVideoParser::PpsData *pps_ptr) { MSG("lists_modification_present_flag = " << pps_ptr->lists_modification_present_flag); MSG("log2_parallel_merge_level_minus2 = " << pps_ptr->log2_parallel_merge_level_minus2); MSG("slice_segment_header_extension_present_flag = " << pps_ptr->slice_segment_header_extension_present_flag); - MSG("pps_extension_present_flag = " << pps_ptr->pps_extension_flag); + MSG("pps_extension_present_flag = " << pps_ptr->pps_extension_present_flag); MSG(""); } @@ -1407,7 +1621,7 @@ void HEVCVideoParser::PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slic MSG("short_term_ref_pic_set_sps_flag = " << slice_header_ptr->short_term_ref_pic_set_sps_flag); MSG("short_term_ref_pic_set_idx = " << slice_header_ptr->short_term_ref_pic_set_idx); - PrintRps(&slice_header_ptr->st_rps); + PrintStRps(&slice_header_ptr->st_rps); MSG("num_long_term_sps = " << slice_header_ptr->num_long_term_sps); MSG("num_long_term_pics = " << slice_header_ptr->num_long_term_pics); @@ -1436,22 +1650,25 @@ void HEVCVideoParser::PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slic MSG_NO_NEWLINE(" " << slice_header_ptr->delta_poc_msb_cycle_lt[i]); } MSG(""); + + PrintLtRefInfo(&slice_header_ptr->lt_rps); + MSG("slice_temporal_mvp_enabled_flag = " << slice_header_ptr->slice_temporal_mvp_enabled_flag); MSG("slice_sao_luma_flag = " << slice_header_ptr->slice_sao_luma_flag); MSG("slice_sao_chroma_flag = " << slice_header_ptr->slice_sao_chroma_flag); - /* Todo MSG("num_ref_idx_active_override_flag = " << slice_header_ptr->num_ref_idx_active_override_flag); - MSG("num_ref_idx_l0_active_minus1 = %d " << slice_header_ptr->num_ref_idx_l0_active_minus1); - MSG("num_ref_idx_l1_active_minus1 = %d " << slice_header_ptr->num_ref_idx_l1_active_minus1); + MSG("num_ref_idx_active_override_flag = " << slice_header_ptr->num_ref_idx_active_override_flag); + MSG("num_ref_idx_l0_active_minus1 = " << slice_header_ptr->num_ref_idx_l0_active_minus1); + MSG("num_ref_idx_l1_active_minus1 = " << slice_header_ptr->num_ref_idx_l1_active_minus1); MSG("ref_pic_list_modification_flag_l0 = " << slice_header_ptr->ref_pic_list_modification_flag_l0); MSG("ref_pic_list_modification_flag_l1 = " << slice_header_ptr->ref_pic_list_modification_flag_l1); MSG_NO_NEWLINE("list_entry_l0[]:"); - for(int i = 0; i < HEVC_MAX_NUM_REF_PICS; i++) { + for(int i = 0; i < 16; i++) { MSG_NO_NEWLINE(" " << slice_header_ptr->list_entry_l0[i]); } MSG(""); MSG_NO_NEWLINE("list_entry_l1[]:"); - for(int i = 0; i < HEVC_MAX_NUM_REF_PICS; i++) { + for(int i = 0; i < 16; i++) { MSG_NO_NEWLINE(" " << slice_header_ptr->list_entry_l1[i]); } MSG(""); @@ -1459,23 +1676,23 @@ void HEVCVideoParser::PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slic MSG("cabac_init_flag = " << slice_header_ptr->cabac_init_flag); MSG("collocated_from_l0_flag = " << slice_header_ptr->collocated_from_l0_flag); MSG("collocated_ref_idx = " << slice_header_ptr->collocated_ref_idx); - MSG("five_minus_max_num_merge_cand = %d " << slice_header_ptr->five_minus_max_num_merge_cand); - MSG("slice_qp_delta = %d " << slice_header_ptr->slice_qp_delta); - MSG("slice_cb_qp_offset = %d " << slice_header_ptr->slice_cb_qp_offset); - MSG("slice_cr_qp_offset = %d " << slice_header_ptr->slice_cr_qp_offset); - MSG("cu_chroma_qp_offset_enabled_flag = %d " << slice_header_ptr->cu_chroma_qp_offset_enabled_flag); - MSG("deblocking_filter_override_flag = %d " << slice_header_ptr->deblocking_filter_override_flag); - MSG("slice_deblocking_filter_disabled_flag = %d " << slice_header_ptr->slice_deblocking_filter_disabled_flag); - MSG("slice_beta_offset_div2 = %d " << slice_header_ptr->slice_beta_offset_div2); - MSG("slice_tc_offset_div2 = %d " << slice_header_ptr->slice_tc_offset_div2); - MSG("slice_loop_filter_across_slices_enabled_flag = %d " << slice_header_ptr->slice_loop_filter_across_slices_enabled_flag); - MSG("num_entry_point_offsets = %d " << slice_header_ptr->num_entry_point_offsets); - MSG("offset_len_minus1 = %d " << slice_header_ptr->offset_len_minus1); - MSG("slice_segment_header_extension_length = %d " << slice_header_ptr->slice_segment_header_extension_length);*/ + MSG("five_minus_max_num_merge_cand = " << slice_header_ptr->five_minus_max_num_merge_cand); + MSG("slice_qp_delta = " << slice_header_ptr->slice_qp_delta); + MSG("slice_cb_qp_offset = " << slice_header_ptr->slice_cb_qp_offset); + MSG("slice_cr_qp_offset = " << slice_header_ptr->slice_cr_qp_offset); + MSG("cu_chroma_qp_offset_enabled_flag = " << slice_header_ptr->cu_chroma_qp_offset_enabled_flag); + MSG("deblocking_filter_override_flag = " << slice_header_ptr->deblocking_filter_override_flag); + MSG("slice_deblocking_filter_disabled_flag = " << slice_header_ptr->slice_deblocking_filter_disabled_flag); + MSG("slice_beta_offset_div2 = " << slice_header_ptr->slice_beta_offset_div2); + MSG("slice_tc_offset_div2 = " << slice_header_ptr->slice_tc_offset_div2); + MSG("slice_loop_filter_across_slices_enabled_flag = " << slice_header_ptr->slice_loop_filter_across_slices_enabled_flag); + MSG("num_entry_point_offsets = " << slice_header_ptr->num_entry_point_offsets); + MSG("offset_len_minus1 = " << slice_header_ptr->offset_len_minus1); + MSG("slice_segment_header_extension_length = " << slice_header_ptr->slice_segment_header_extension_length); MSG(""); } -void HEVCVideoParser::PrintRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr) { +void HEVCVideoParser::PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr) { MSG("==== Short-term reference picture set =====") MSG("inter_ref_pic_set_prediction_flag = " << rps_ptr->inter_ref_pic_set_prediction_flag); MSG("delta_idx_minus1 = " << rps_ptr->delta_idx_minus1); @@ -1528,4 +1745,19 @@ void HEVCVideoParser::PrintRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr) { } MSG(""); } + +void HEVCVideoParser::PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_ptr) { + MSG("==== Long-term reference picture info ====="); + MSG("num_of_pics = " << lt_info_ptr->num_of_pics); + MSG_NO_NEWLINE("pocs[]:"); + for(int j = 0; j < 32; j++) { + MSG_NO_NEWLINE(" " << lt_info_ptr->pocs[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic[]:"); + for(int j = 0; j < 32; j++) { + MSG_NO_NEWLINE(" " << lt_info_ptr->used_by_curr_pic[j]); + } + MSG(""); +} #endif // DBGINFO \ No newline at end of file diff --git a/src/parser/hevc_parser.h b/src/parser/hevc_parser.h index a66317177c..804a9efe26 100644 --- a/src/parser/hevc_parser.h +++ b/src/parser/hevc_parser.h @@ -170,6 +170,14 @@ protected: H265_SCALING_LIST_SIZE_NUM }; + /*! \brief Slice type + */ + enum HevcSliceType { + HEVC_SLICE_TYPE_B = 0, + HEVC_SLICE_TYPE_P, + HEVC_SLICE_TYPE_I + }; + /*! \brief Structure for Profile Tier Levels */ typedef struct { @@ -328,6 +336,23 @@ protected: uint32_t log2_max_mv_length_vertical; //ue(v) } H265VuiParameters; + typedef struct { + uint32_t luma_log2_weight_denom; //ue(v) + int32_t delta_chroma_log2_weight_denom; //se(v) + uint8_t luma_weight_l0_flag[16]; //u(1) + uint8_t chroma_weight_l0_flag[16]; //u(1) + int32_t delta_luma_weight_l0[16]; //se(v) + int32_t luma_offset_l0[16]; //se(v) + int32_t delta_chroma_weight_l0[16][2]; //se(v) + int32_t delta_chroma_offset_l0[16][2]; //se(v) + uint8_t luma_weight_l1_flag[16]; //u(1) + uint8_t chroma_weight_l1_flag[16]; //u(1) + int32_t delta_luma_weight_l1[16]; //se(v) + int32_t luma_offset_l1[16]; //se(v) + int32_t delta_chroma_weight_l1[16][2]; //se(v) + int32_t delta_chroma_offset_l1[16][2]; //se(v) + } HevcPredWeightTable; + /*! \brief Structure for Raw Byte Sequence Payload Trialing Bits */ typedef struct { @@ -488,7 +513,20 @@ protected: bool lists_modification_present_flag; //u(1) uint32_t log2_parallel_merge_level_minus2; //ue(v) bool slice_segment_header_extension_present_flag; //u(1) - bool pps_extension_flag; //u(1) + bool pps_extension_present_flag; //u(1) + bool pps_range_extension_flag; //u(1) + bool pps_multilayer_extension_flag; //u(1) + uint32_t pps_extension_6bits; //u(6) + // pps_range_extension() + uint32_t log2_max_transform_skip_block_size_minus2; //ue(v) + uint8_t cross_component_prediction_enabled_flag; //u(1) + uint8_t chroma_qp_offset_list_enabled_flag; //u(1) + uint32_t diff_cu_chroma_qp_offset_depth; //ue(v) + uint32_t chroma_qp_offset_list_len_minus1; //ue(v) + int32_t cb_qp_offset_list[6]; //se(v) + int32_t cr_qp_offset_list[6]; //se(v) + uint32_t log2_sao_offset_scale_luma; //ue(v) + uint32_t log2_sao_offset_scale_chroma; //ue(v) bool pps_extension_data_flag; //u(1) //rbsp_trailing_bits( ) H265RbspTrailingBits rbsp_trailing_bits; @@ -540,14 +578,21 @@ protected: bool num_ref_idx_active_override_flag; //u(1) uint32_t num_ref_idx_l0_active_minus1; //ue(v) uint32_t num_ref_idx_l1_active_minus1; //ue(v) + // Reference picture list modification + uint32_t ref_pic_list_modification_flag_l0; //u(1) + uint32_t list_entry_l0[16]; //u(v) + uint32_t ref_pic_list_modification_flag_l1; //u(1) + uint32_t list_entry_l1[16]; //u(v) bool mvd_l1_zero_flag; //u(1) bool cabac_init_flag; //u(1) bool collocated_from_l0_flag; //u(1) + HevcPredWeightTable pred_weight_table; uint32_t collocated_ref_idx; //ue(v) uint32_t five_minus_max_num_merge_cand; //ue(v) int32_t slice_qp_delta; //se(v) int32_t slice_cb_qp_offset; //se(v) int32_t slice_cr_qp_offset; //se(v) + uint8_t cu_chroma_qp_offset_enabled_flag; //u(1) bool deblocking_filter_override_flag; //u(1) bool slice_deblocking_filter_disabled_flag; //u(1) int32_t slice_beta_offset_div2; //se(v) @@ -705,8 +750,16 @@ protected: * \param [in] offset Reference to the offset in the input buffer * \return No return value */ - void ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_rps_idx, uint32_t num_short_term_ref_pic_sets, H265ShortTermRPS rps_ref[], uint8_t *data, size_t size,size_t &offset); + void ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_rps_idx, uint32_t num_short_term_ref_pic_sets, H265ShortTermRPS rps_ref[], uint8_t *data, size_t size, size_t &offset); + /*! \brief Function to parse weighted prediction table + * \param [in/out] Slice_header_ptr Pointer to the slice segment header + * \param [in] chroma_array_type ChromaArrayType + * \param [in] stream_ptr Bit stream pointer + * \param [in/out] offset Bit offset of the current parsing action + */ + void ParsePredWeightTable(HEVCVideoParser::SliceHeaderData *slice_header_ptr, int chroma_array_type, uint8_t *stream_ptr, size_t &offset); + /*! \brief Function to parse Slice Header * \param [in] nal_unit_type Input of uint32_t containing the enumerator value to the NAL Unit Type * \param [in] nalu A pointer of uint8_t for the input stream to be parsed @@ -732,7 +785,8 @@ protected: void PrintSps(HEVCVideoParser::SpsData *sps_ptr); void PrintPps(HEVCVideoParser::PpsData *pps_ptr); void PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slice_header_ptr); - void PrintRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr); + void PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr); + void PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_ptr); #endif // DBGINFO private: