diff --git a/projects/rocdecode/src/parser/hevc_parser.cpp b/projects/rocdecode/src/parser/hevc_parser.cpp index 06189fefbf..035d04307d 100644 --- a/projects/rocdecode/src/parser/hevc_parser.cpp +++ b/projects/rocdecode/src/parser/hevc_parser.cpp @@ -285,7 +285,7 @@ int HEVCVideoParser::GetNalUnit() { } } -void HEVCVideoParser::ParsePtl(H265ProfileTierLevel *ptl, bool profile_present_flag, uint32_t max_num_sub_layers_minus1, uint8_t *nalu, size_t /*size*/, size_t& offset) { +void HEVCVideoParser::ParsePtl(H265ProfileTierLevel *ptl, bool profile_present_flag, uint32_t max_num_sub_layers_minus1, uint8_t *nalu, size_t size, size_t& offset) { if (profile_present_flag) { ptl->general_profile_space = Parser::ReadBits(nalu, offset, 2); ptl->general_tier_flag = Parser::GetBit(nalu, offset); @@ -297,9 +297,9 @@ void HEVCVideoParser::ParsePtl(H265ProfileTierLevel *ptl, bool profile_present_f ptl->general_interlaced_source_flag = Parser::GetBit(nalu, offset); ptl->general_non_packed_constraint_flag = Parser::GetBit(nalu, offset); ptl->general_frame_only_constraint_flag = Parser::GetBit(nalu, offset); - //ReadBits is limited to 32 - offset += 44; - // Todo: add constrant flags parsing. + // ReadBits is limited to 32 + offset += 44; // skip 44 bits + // Todo: add constrant flags parsing for higher profiles when needed } ptl->general_level_idc = Parser::ReadBits(nalu, offset, 8); @@ -324,7 +324,9 @@ void HEVCVideoParser::ParsePtl(H265ProfileTierLevel *ptl, bool profile_present_f ptl->sub_layer_interlaced_source_flag[i] = Parser::GetBit(nalu, offset); ptl->sub_layer_non_packed_constraint_flag[i] = Parser::GetBit(nalu, offset); ptl->sub_layer_frame_only_constraint_flag[i] = Parser::GetBit(nalu, offset); - ptl->sub_layer_reserved_zero_44bits[i] = Parser::ReadBits(nalu, offset, 44); + // ReadBits is limited to 32 + offset += 44; // skip 44 bits + // Todo: add constrant flags parsing for higher profiles when needed } if (ptl->sub_layer_level_present_flag[i]) { ptl->sub_layer_level_idc[i] = Parser::ReadBits(nalu, offset, 8); @@ -395,127 +397,213 @@ void HEVCVideoParser::ParseHrdParameters(H265HrdParameters *hrd, bool common_inf } } -void HEVCVideoParser::ParseScalingList(H265ScalingListData * s_data, uint8_t *nalu, size_t /*size*/, size_t& offset) { - for (int size_id = 0; size_id < 4; size_id++) { - for (int matrix_id = 0; matrix_id < ((size_id == 3) ? 2 : 6); matrix_id++) { - s_data->scaling_list_pred_mode_flag[size_id][matrix_id] = Parser::GetBit(nalu, offset); - if(!s_data->scaling_list_pred_mode_flag[size_id][matrix_id]) { - s_data->scaling_list_pred_matrix_id_delta[size_id][matrix_id] = Parser::ExpGolomb::ReadUe(nalu, offset); +// Table 7-5. Default values of ScalingList[ 0 ][ matrixId ][ i ] with i = 0..15. +static const uint8_t default_scaling_list_side_id_0[] = { + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16 +}; - int ref_matrix_id = matrix_id - s_data->scaling_list_pred_matrix_id_delta[size_id][matrix_id]; - int coef_num = std::min(64, (1 << (4 + (size_id << 1)))); +// Table 7-6. Default values of ScalingList[ 1..3 ][ 0..2 ][ i ] with i = 0..63. +static const uint8_t default_scaling_list_intra[] = { + 16, 16, 16, 16, 17, 18, 21, 24, + 16, 16, 16, 16, 17, 19, 22, 25, + 16, 16, 17, 18, 20, 22, 25, 29, + 16, 16, 18, 21, 24, 27, 31, 36, + 17, 17, 20, 24, 30, 35, 41, 47, + 18, 19, 22, 27, 35, 44, 54, 65, + 21, 22, 25, 31, 41, 54, 70, 88, + 24, 25, 29, 36, 47, 65, 88, 115 +}; - //fill in scaling_list_dc_coef_minus8 - if (!s_data->scaling_list_pred_matrix_id_delta[size_id][matrix_id]) { - if (size_id > 1) { - s_data->scaling_list_dc_coef_minus8[size_id - 2][matrix_id] = 8; - } - } - else { - if (size_id > 1) { - s_data->scaling_list_dc_coef_minus8[size_id-2][matrix_id] = s_data->scaling_list_dc_coef_minus8[size_id-2][ref_matrix_id]; - } - } +// Table 7-6. Default values of ScalingList[ 1..3 ][ 3..5 ][ i ] with i = 0..63. +static const uint8_t default_scaling_list_inter[] = { + 16, 16, 16, 16, 17, 18, 20, 24, + 16, 16, 16, 17, 18, 20, 24, 25, + 16, 16, 17, 18, 20, 24, 25, 28, + 16, 17, 18, 20, 24, 25, 28, 33, + 17, 18, 20, 24, 25, 28, 33, 41, + 18, 20, 24, 25, 28, 33, 41, 54, + 20, 24, 25, 28, 33, 41, 54, 71, + 24, 25, 28, 33, 41, 54, 71, 91 +}; - for (int i = 0; i < coef_num; i++) { - if (s_data->scaling_list_pred_matrix_id_delta[size_id][matrix_id] == 0) { - if (size_id == 0) { - s_data->scaling_list[size_id][matrix_id][i] = scaling_list_default_0[size_id][matrix_id][i]; - } - else if(size_id == 1 || size_id == 2) { - s_data->scaling_list[size_id][matrix_id][i] = scaling_list_default_1_2[size_id][matrix_id][i]; - } - else if(size_id == 3) { - s_data->scaling_list[size_id][matrix_id][i] = scaling_list_default_3[size_id][matrix_id][i]; - } - } - else { - s_data->scaling_list[size_id][matrix_id][i] = s_data->scaling_list[size_id][ref_matrix_id][i]; - } - } +static const int diag_scan_4x4[16] = { + 0, 4, 1, 8, + 5, 2,12, 9, + 6, 3,13,10, + 7,14,11,15 +}; + +static const int diag_scan_8x8[64] = { + 0, 8, 1, 16, 9, 2,24,17, + 10, 3,32,25,18,11, 4,40, + 33,26,19,12, 5,48,41,34, + 27,20,13, 6,56,49,42,35, + 28,21,14, 7,57,50,43,36, + 29,22,15,58,51,44,37,30, + 23,59,52,45,38,31,60,53, + 46,39,61,54,47,62,55,63 +}; + +void HEVCVideoParser::SetDefaultScalingList(H265ScalingListData *sl_ptr) { + int size_id, matrix_id, i; + + // DC coefficient for 16x16 and 32x32 + for (matrix_id = 0; matrix_id < 6; matrix_id++) { + sl_ptr->scaling_list_dc_coef[0][matrix_id] = 16; + sl_ptr->scaling_list_dc_coef[1][matrix_id] = 16; + } + + // sizeId 0 + for (matrix_id = 0; matrix_id < 6; matrix_id++) { + for (i = 0; i < 16; i++) { + sl_ptr->scaling_list[0][matrix_id][i] = default_scaling_list_side_id_0[i]; + } + } + + // sizeId 1..3, matrixId 0..2 + for (size_id = 1; size_id <= 3; size_id++) { + for (matrix_id = 0; matrix_id <= 2; matrix_id++) { + for (i = 0; i < 64; i++) { + sl_ptr->scaling_list[size_id][matrix_id][i] = default_scaling_list_intra[i]; } - else { - int next_coef = 8; - int coef_num = std::min(64, (1 << (4 + (size_id << 1)))); - if (size_id > 1) { - s_data->scaling_list_dc_coef_minus8[size_id - 2][matrix_id] = Parser::ExpGolomb::ReadSe(nalu, offset); - next_coef = s_data->scaling_list_dc_coef_minus8[size_id - 2][matrix_id] + 8; - } - for (int i = 0; i < coef_num; i++) { - s_data->scaling_list_delta_coef = Parser::ExpGolomb::ReadSe(nalu, offset); - next_coef = (next_coef + s_data->scaling_list_delta_coef +256) % 256; - s_data->scaling_list[size_id][matrix_id][i] = next_coef; - } + } + } + + // sizeId 1..3, matrixId 3..5 + for (size_id = 1; size_id <= 3; size_id++) { + for (matrix_id = 3; matrix_id <= 5; matrix_id++) { + for (i = 0; i < 64; i++) { + sl_ptr->scaling_list[size_id][matrix_id][i] = default_scaling_list_inter[i]; } } } } +void HEVCVideoParser::ParseScalingList(H265ScalingListData * sl_ptr, uint8_t *nalu, size_t size, size_t& offset, SpsData *sps_ptr) { + for (int size_id = 0; size_id < 4; size_id++) { + for (int matrix_id = 0; matrix_id < 6; matrix_id += (size_id == 3) ? 3 : 1) { + sl_ptr->scaling_list_pred_mode_flag[size_id][matrix_id] = Parser::GetBit(nalu, offset); + if(!sl_ptr->scaling_list_pred_mode_flag[size_id][matrix_id]) { + sl_ptr->scaling_list_pred_matrix_id_delta[size_id][matrix_id] = Parser::ExpGolomb::ReadUe(nalu, offset); + // If scaling_list_pred_matrix_id_delta is 0, infer from default scaling list. We have filled the scaling + // list with default values earlier. + if (sl_ptr->scaling_list_pred_matrix_id_delta[size_id][matrix_id]) { + // Infer from the reference scaling list + int ref_matrix_id = matrix_id - sl_ptr->scaling_list_pred_matrix_id_delta[size_id][matrix_id] * (size_id == 3 ? 3 : 1); + int coef_num = std::min(64, (1 << (4 + (size_id << 1)))); + for (int i = 0; i < coef_num; i++) { + sl_ptr->scaling_list[size_id][matrix_id][i] = sl_ptr->scaling_list[size_id][ref_matrix_id][i]; + } + + // Copy to DC coefficient for 16x16 or 32x32 + if (size_id > 1) { + sl_ptr->scaling_list_dc_coef[size_id - 2][matrix_id] = sl_ptr->scaling_list_dc_coef[size_id - 2][ref_matrix_id]; + } + } + } + else { + int next_coef = 8; + int coef_num = std::min(64, (1 << (4 + (size_id << 1)))); + if (size_id > 1) { + sl_ptr->scaling_list_dc_coef_minus8[size_id - 2][matrix_id] = Parser::ExpGolomb::ReadSe(nalu, offset); + next_coef = sl_ptr->scaling_list_dc_coef_minus8[size_id - 2][matrix_id] + 8; + // Record DC coefficient for 16x16 or 32x32 + sl_ptr->scaling_list_dc_coef[size_id - 2][matrix_id] = next_coef; + } + for (int i = 0; i < coef_num; i++) { + sl_ptr->scaling_list_delta_coef = Parser::ExpGolomb::ReadSe(nalu, offset); + next_coef = (next_coef + sl_ptr->scaling_list_delta_coef + 256) % 256; + if (size_id == 0) { + sl_ptr->scaling_list[size_id][matrix_id][diag_scan_4x4[i]] = next_coef; + } + else { + sl_ptr->scaling_list[size_id][matrix_id][diag_scan_8x8[i]] = next_coef; + } + } + } + } + } + + if (sps_ptr->chroma_format_idc == 3) { + for (int i = 0; i < 64; i++) { + sl_ptr->scaling_list[3][1][i] = sl_ptr->scaling_list[2][1][i]; + sl_ptr->scaling_list[3][2][i] = sl_ptr->scaling_list[2][2][i]; + sl_ptr->scaling_list[3][4][i] = sl_ptr->scaling_list[2][4][i]; + sl_ptr->scaling_list[3][5][i] = sl_ptr->scaling_list[2][5][i]; + } + sl_ptr->scaling_list_dc_coef[1][1] = sl_ptr->scaling_list_dc_coef[0][1]; + sl_ptr->scaling_list_dc_coef[1][2] = sl_ptr->scaling_list_dc_coef[0][2]; + sl_ptr->scaling_list_dc_coef[1][4] = sl_ptr->scaling_list_dc_coef[0][4]; + sl_ptr->scaling_list_dc_coef[1][5] = sl_ptr->scaling_list_dc_coef[0][5]; + } +} + void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_rps_idx, uint32_t number_short_term_ref_pic_sets, H265ShortTermRPS rps_ref[], uint8_t *nalu, size_t /*size*/, size_t& offset) { - uint32_t inter_rps_pred = 0; - uint32_t delta_idx_minus1 = 0; int32_t i = 0; if (st_rps_idx != 0) { - inter_rps_pred = Parser::GetBit(nalu, offset); + rps->inter_ref_pic_set_prediction_flag = Parser::GetBit(nalu, offset); } - if (inter_rps_pred) { - uint32_t delta_rps_sign, abs_delta_rps_minus1; - bool used_by_curr_pic_flag[16] = {0}; - bool use_delta_flag[16] = {0}; + else { + rps->inter_ref_pic_set_prediction_flag = 0; + } + if (rps->inter_ref_pic_set_prediction_flag) { if (unsigned(st_rps_idx) == number_short_term_ref_pic_sets) { - delta_idx_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + rps->delta_idx_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); } - delta_rps_sign = Parser::GetBit(nalu, offset); - abs_delta_rps_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - int32_t delta_rps = (int32_t) (1 - 2 * delta_rps_sign) * (abs_delta_rps_minus1 + 1); - int32_t ref_idx = st_rps_idx - delta_idx_minus1 - 1; - for (int j = 0; j <= (rps_ref[ref_idx].num_negative_pics + rps_ref[ref_idx].num_positive_pics); j++) { - used_by_curr_pic_flag[j] = Parser::GetBit(nalu, offset); - if (!used_by_curr_pic_flag[j]) { - use_delta_flag[j] = Parser::GetBit(nalu, offset); + else { + rps->delta_idx_minus1 = 0; + } + rps->delta_rps_sign = Parser::GetBit(nalu, offset); + rps->abs_delta_rps_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + int32_t delta_rps = (int32_t) (1 - 2 * rps->delta_rps_sign) * (rps->abs_delta_rps_minus1 + 1); + int32_t ref_idx = st_rps_idx - rps->delta_idx_minus1 - 1; + for (int j = 0; j <= (rps_ref[ref_idx].num_of_delta_poc); j++) { + rps->used_by_curr_pic_flag[j] = Parser::GetBit(nalu, offset); + if (!rps->used_by_curr_pic_flag[j]) { + rps->use_delta_flag[j] = Parser::GetBit(nalu, offset); } else { - use_delta_flag[j] = 1; + rps->use_delta_flag[j] = 1; } } for (int j = rps_ref[ref_idx].num_positive_pics - 1; j >= 0; j--) { int32_t delta_poc = delta_rps + rps_ref[ref_idx].delta_poc[rps_ref[ref_idx].num_negative_pics + j]; //positive delta_poc from ref_rps - if (delta_poc < 0 && use_delta_flag[rps_ref[ref_idx].num_negative_pics + j]) { + if (delta_poc < 0 && rps->use_delta_flag[rps_ref[ref_idx].num_negative_pics + j]) { rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics + j]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics + j]; } } - if (delta_rps < 0 && use_delta_flag[rps_ref[ref_idx].num_of_pics]) { + if (delta_rps < 0 && rps->use_delta_flag[rps_ref[ref_idx].num_of_pics]) { rps->delta_poc[i] = delta_rps; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; } for (int j = 0; j < rps_ref[ref_idx].num_negative_pics; j++) { int32_t delta_poc = delta_rps + rps_ref[ref_idx].delta_poc[j]; - if (delta_poc < 0 && use_delta_flag[j]) { + if (delta_poc < 0 && rps->use_delta_flag[j]) { rps->delta_poc[i]=delta_poc; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[j]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[j]; } } rps->num_negative_pics = i; for (int j = rps_ref[ref_idx].num_negative_pics - 1; j >= 0; j--) { int32_t delta_poc = delta_rps + rps_ref[ref_idx].delta_poc[j]; //positive delta_poc from ref_rps - if (delta_poc > 0 && use_delta_flag[j]) { + if (delta_poc > 0 && rps->use_delta_flag[j]) { rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[j]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[j]; } } - if (delta_rps > 0 && use_delta_flag[rps_ref[ref_idx].num_of_pics]) { + if (delta_rps > 0 && rps->use_delta_flag[rps_ref[ref_idx].num_of_pics]) { rps->delta_poc[i] = delta_rps; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; } for (int j = 0; j < rps_ref[ref_idx].num_positive_pics; j++) { int32_t delta_poc = delta_rps + rps_ref[ref_idx].delta_poc[rps_ref[ref_idx].num_negative_pics+j]; - if (delta_poc > 0 && use_delta_flag[rps_ref[ref_idx].num_negative_pics+j]) { + if (delta_poc > 0 && rps->use_delta_flag[rps_ref[ref_idx].num_negative_pics+j]) { rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics+j]; + rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics+j]; } } rps->num_positive_pics = i - rps->num_negative_pics ; @@ -527,21 +615,24 @@ void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_ rps->num_positive_pics = Parser::ExpGolomb::ReadUe(nalu, offset); int32_t prev = 0; int32_t poc; - uint32_t delta_poc_s0_minus1,delta_poc_s1_minus1; + // DeltaPocS0, UsedByCurrPicS0 for (int j = 0; j < rps->num_negative_pics; j++) { - delta_poc_s0_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - poc = prev - delta_poc_s0_minus1 - 1; + rps->delta_poc_s0_minus1[j] = Parser::ExpGolomb::ReadUe(nalu, offset); + poc = prev - rps->delta_poc_s0_minus1[j] - 1; prev = poc; - rps->delta_poc[j] = poc; - rps->used_by_curr_pic[j] = Parser::GetBit(nalu, offset); + rps->delta_poc[j] = poc; // DeltaPocS0 + rps->used_by_curr_pic_s0_flag[j] = Parser::GetBit(nalu, offset); + rps->used_by_curr_pic[j] = rps->used_by_curr_pic_s0_flag[j]; // UsedByCurrPicS0 } prev = 0; - for (int j = rps->num_negative_pics; j < rps->num_negative_pics + rps->num_positive_pics; j++) { - delta_poc_s1_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - poc = prev + delta_poc_s1_minus1 + 1; + // DeltaPocS1, UsedByCurrPicS1 + for (int j = 0; j < rps->num_positive_pics; j++) { + rps->delta_poc_s1_minus1[j] = Parser::ExpGolomb::ReadUe(nalu, offset); + poc = prev + rps->delta_poc_s1_minus1[j] + 1; prev = poc; - rps->delta_poc[j] = poc; - rps->used_by_curr_pic[j] = Parser::GetBit(nalu, offset); + rps->delta_poc[j + rps->num_negative_pics] = poc; // DeltaPocS1 + rps->used_by_curr_pic_s1_flag[j] = Parser::GetBit(nalu, offset); + rps->used_by_curr_pic[j + rps->num_negative_pics] = rps->used_by_curr_pic_s1_flag[j]; // UsedByCurrPicS1 } rps->num_of_pics = rps->num_negative_pics + rps->num_positive_pics; rps->num_of_delta_poc = rps->num_negative_pics + rps->num_positive_pics; @@ -672,186 +763,201 @@ void HEVCVideoParser::ParseVps(uint8_t *nalu, size_t size) { #endif // DBGINFO } -void HEVCVideoParser::ParseSps(uint8_t *nalu, size_t size) { +void HEVCVideoParser::ParseSps(uint8_t *nalu, size_t size) { + SpsData *sps_ptr = NULL; size_t offset = 0; + uint32_t vps_id = Parser::ReadBits(nalu, offset, 4); uint32_t max_sub_layer_minus1 = Parser::ReadBits(nalu, offset, 3); uint32_t sps_temporal_id_nesting_flag = Parser::GetBit(nalu, offset); H265ProfileTierLevel ptl; memset (&ptl, 0, sizeof(ptl)); ParsePtl(&ptl, true, max_sub_layer_minus1, nalu, size, offset); + uint32_t sps_id = Parser::ExpGolomb::ReadUe(nalu, offset); - memset(&m_sps_[sps_id], 0, sizeof(m_sps_[sps_id])); - m_sps_[sps_id].sps_video_parameter_set_id = vps_id; - m_sps_[sps_id].sps_max_sub_layers_minus1 = max_sub_layer_minus1; - m_sps_[sps_id].sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag; - memcpy (&m_sps_[sps_id].profile_tier_level, &ptl, sizeof(ptl)); - m_sps_[sps_id].sps_seq_parameter_set_id = sps_id; - m_sps_[sps_id].chroma_format_idc = Parser::ExpGolomb::ReadUe(nalu, offset); - if (m_sps_[sps_id].chroma_format_idc == 3) { - m_sps_[sps_id].separate_colour_plane_flag = Parser::GetBit(nalu, offset); + sps_ptr = &m_sps_[sps_id]; + + memset(sps_ptr, 0, sizeof(SpsData)); + sps_ptr->sps_video_parameter_set_id = vps_id; + sps_ptr->sps_max_sub_layers_minus1 = max_sub_layer_minus1; + sps_ptr->sps_temporal_id_nesting_flag = sps_temporal_id_nesting_flag; + memcpy (&sps_ptr->profile_tier_level, &ptl, sizeof(ptl)); + sps_ptr->sps_seq_parameter_set_id = sps_id; + sps_ptr->chroma_format_idc = Parser::ExpGolomb::ReadUe(nalu, offset); + if (sps_ptr->chroma_format_idc == 3) { + sps_ptr->separate_colour_plane_flag = Parser::GetBit(nalu, offset); } - m_sps_[sps_id].pic_width_in_luma_samples = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].pic_height_in_luma_samples = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].conformance_window_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].conformance_window_flag) - { - m_sps_[sps_id].conf_win_left_offset = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].conf_win_right_offset = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].conf_win_top_offset = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].conf_win_bottom_offset = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->pic_width_in_luma_samples = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->pic_height_in_luma_samples = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->conformance_window_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->conformance_window_flag) { + sps_ptr->conf_win_left_offset = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->conf_win_right_offset = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->conf_win_top_offset = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->conf_win_bottom_offset = Parser::ExpGolomb::ReadUe(nalu, offset); } - m_sps_[sps_id].bit_depth_luma_minus8 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].bit_depth_chroma_minus8 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].log2_max_pic_order_cnt_lsb_minus4 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].sps_sub_layer_ordering_info_present_flag = Parser::GetBit(nalu, offset); - for (int i = 0; i <= m_sps_[sps_id].sps_max_sub_layers_minus1; i++) { - if (m_sps_[sps_id].sps_sub_layer_ordering_info_present_flag || (i == 0)) { - m_sps_[sps_id].sps_max_dec_pic_buffering_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].sps_max_num_reorder_pics[i] = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].sps_max_latency_increase_plus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->bit_depth_luma_minus8 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->bit_depth_chroma_minus8 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->log2_max_pic_order_cnt_lsb_minus4 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->sps_sub_layer_ordering_info_present_flag = Parser::GetBit(nalu, offset); + for (int i = 0; i <= sps_ptr->sps_max_sub_layers_minus1; i++) { + if (sps_ptr->sps_sub_layer_ordering_info_present_flag || (i == 0)) { + sps_ptr->sps_max_dec_pic_buffering_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->sps_max_num_reorder_pics[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->sps_max_latency_increase_plus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); } else { - m_sps_[sps_id].sps_max_dec_pic_buffering_minus1[i] = m_sps_[sps_id].sps_max_dec_pic_buffering_minus1[0]; - m_sps_[sps_id].sps_max_num_reorder_pics[i] = m_sps_[sps_id].sps_max_num_reorder_pics[0]; - m_sps_[sps_id].sps_max_latency_increase_plus1[i] = m_sps_[sps_id].sps_max_latency_increase_plus1[0]; + sps_ptr->sps_max_dec_pic_buffering_minus1[i] = sps_ptr->sps_max_dec_pic_buffering_minus1[0]; + sps_ptr->sps_max_num_reorder_pics[i] = sps_ptr->sps_max_num_reorder_pics[0]; + sps_ptr->sps_max_latency_increase_plus1[i] = sps_ptr->sps_max_latency_increase_plus1[0]; } } - m_sps_[sps_id].log2_min_luma_coding_block_size_minus3 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->log2_min_luma_coding_block_size_minus3 = Parser::ExpGolomb::ReadUe(nalu, offset); - int log2_min_cu_size = m_sps_[sps_id].log2_min_luma_coding_block_size_minus3 + 3; + int log2_min_cu_size = sps_ptr->log2_min_luma_coding_block_size_minus3 + 3; - m_sps_[sps_id].log2_diff_max_min_luma_coding_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->log2_diff_max_min_luma_coding_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); - int max_cu_depth_delta = m_sps_[sps_id].log2_diff_max_min_luma_coding_block_size; - m_sps_[sps_id].max_cu_width = ( 1<<(log2_min_cu_size + max_cu_depth_delta)); - m_sps_[sps_id].max_cu_height = ( 1<<(log2_min_cu_size + max_cu_depth_delta)); + int max_cu_depth_delta = sps_ptr->log2_diff_max_min_luma_coding_block_size; + sps_ptr->max_cu_width = ( 1<<(log2_min_cu_size + max_cu_depth_delta)); + sps_ptr->max_cu_height = ( 1<<(log2_min_cu_size + max_cu_depth_delta)); - m_sps_[sps_id].log2_min_transform_block_size_minus2 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->log2_min_transform_block_size_minus2 = Parser::ExpGolomb::ReadUe(nalu, offset); - uint32_t quadtree_tu_log2_min_size = m_sps_[sps_id].log2_min_transform_block_size_minus2 + 2; + uint32_t quadtree_tu_log2_min_size = sps_ptr->log2_min_transform_block_size_minus2 + 2; int add_cu_depth = max (0, log2_min_cu_size - (int)quadtree_tu_log2_min_size); - m_sps_[sps_id].max_cu_depth = (max_cu_depth_delta + add_cu_depth); + sps_ptr->max_cu_depth = (max_cu_depth_delta + add_cu_depth); - m_sps_[sps_id].log2_diff_max_min_transform_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].max_transform_hierarchy_depth_inter = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].max_transform_hierarchy_depth_intra = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].scaling_list_enabled_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].scaling_list_enabled_flag) { - m_sps_[sps_id].sps_scaling_list_data_present_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].sps_scaling_list_data_present_flag) { - ParseScalingList(&m_sps_[sps_id].scaling_list_data, nalu, size, offset); + sps_ptr->log2_diff_max_min_transform_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->max_transform_hierarchy_depth_inter = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->max_transform_hierarchy_depth_intra = Parser::ExpGolomb::ReadUe(nalu, offset); + + sps_ptr->scaling_list_enabled_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->scaling_list_enabled_flag) { + // Set up default values first + SetDefaultScalingList(&sps_ptr->scaling_list_data); + + sps_ptr->sps_scaling_list_data_present_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->sps_scaling_list_data_present_flag) { + ParseScalingList(&sps_ptr->scaling_list_data, nalu, size, offset, sps_ptr); } } - m_sps_[sps_id].amp_enabled_flag = Parser::GetBit(nalu, offset); - m_sps_[sps_id].sample_adaptive_offset_enabled_flag = Parser::GetBit(nalu, offset); - m_sps_[sps_id].pcm_enabled_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].pcm_enabled_flag) { - m_sps_[sps_id].pcm_sample_bit_depth_luma_minus1 = Parser::ReadBits(nalu, offset, 4); - m_sps_[sps_id].pcm_sample_bit_depth_chroma_minus1 = Parser::ReadBits(nalu, offset, 4); - m_sps_[sps_id].log2_min_pcm_luma_coding_block_size_minus3 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].log2_diff_max_min_pcm_luma_coding_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); - m_sps_[sps_id].pcm_loop_filter_disabled_flag = Parser::GetBit(nalu, offset); + sps_ptr->amp_enabled_flag = Parser::GetBit(nalu, offset); + sps_ptr->sample_adaptive_offset_enabled_flag = Parser::GetBit(nalu, offset); + sps_ptr->pcm_enabled_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->pcm_enabled_flag) { + sps_ptr->pcm_sample_bit_depth_luma_minus1 = Parser::ReadBits(nalu, offset, 4); + sps_ptr->pcm_sample_bit_depth_chroma_minus1 = Parser::ReadBits(nalu, offset, 4); + sps_ptr->log2_min_pcm_luma_coding_block_size_minus3 = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->log2_diff_max_min_pcm_luma_coding_block_size = Parser::ExpGolomb::ReadUe(nalu, offset); + sps_ptr->pcm_loop_filter_disabled_flag = Parser::GetBit(nalu, offset); } - m_sps_[sps_id].num_short_term_ref_pic_sets = Parser::ExpGolomb::ReadUe(nalu, offset); - for (int i=0; inum_short_term_ref_pic_sets = Parser::ExpGolomb::ReadUe(nalu, offset); + for (int i=0; inum_short_term_ref_pic_sets; i++) { //short_term_ref_pic_set( i ) - ParseShortTermRefPicSet(&m_sps_[sps_id].st_rps[i], i, m_sps_[sps_id].num_short_term_ref_pic_sets, m_sps_[sps_id].st_rps, nalu, size, offset); + ParseShortTermRefPicSet(&sps_ptr->st_rps[i], i, sps_ptr->num_short_term_ref_pic_sets, sps_ptr->st_rps, nalu, size, offset); } - m_sps_[sps_id].long_term_ref_pics_present_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].long_term_ref_pics_present_flag) { - m_sps_[sps_id].num_long_term_ref_pics_sps = Parser::ExpGolomb::ReadUe(nalu, offset); //max is 32 - m_sps_[sps_id].lt_rps.num_of_pics = m_sps_[sps_id].num_long_term_ref_pics_sps; - for (int i=0; ilong_term_ref_pics_present_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->long_term_ref_pics_present_flag) { + sps_ptr->num_long_term_ref_pics_sps = Parser::ExpGolomb::ReadUe(nalu, offset); //max is 32 + sps_ptr->lt_rps.num_of_pics = sps_ptr->num_long_term_ref_pics_sps; + for (int i=0; inum_long_term_ref_pics_sps; i++) { //The number of bits used to represent lt_ref_pic_poc_lsb_sps[ i ] is equal to log2_max_pic_order_cnt_lsb_minus4 + 4. - m_sps_[sps_id].lt_ref_pic_poc_lsb_sps[i] = Parser::ReadBits(nalu, offset, (m_sps_[sps_id].log2_max_pic_order_cnt_lsb_minus4 + 4)); - m_sps_[sps_id].used_by_curr_pic_lt_sps_flag[i] = Parser::GetBit(nalu, offset); - m_sps_[sps_id].lt_rps.pocs[i]=m_sps_[sps_id].lt_ref_pic_poc_lsb_sps[i]; - m_sps_[sps_id].lt_rps.used_by_curr_pic[i] = m_sps_[sps_id].used_by_curr_pic_lt_sps_flag[i]; + sps_ptr->lt_ref_pic_poc_lsb_sps[i] = Parser::ReadBits(nalu, offset, (sps_ptr->log2_max_pic_order_cnt_lsb_minus4 + 4)); + sps_ptr->used_by_curr_pic_lt_sps_flag[i] = Parser::GetBit(nalu, offset); + sps_ptr->lt_rps.pocs[i]=sps_ptr->lt_ref_pic_poc_lsb_sps[i]; + sps_ptr->lt_rps.used_by_curr_pic[i] = sps_ptr->used_by_curr_pic_lt_sps_flag[i]; } } - m_sps_[sps_id].sps_temporal_mvp_enabled_flag = Parser::GetBit(nalu, offset); - m_sps_[sps_id].strong_intra_smoothing_enabled_flag = Parser::GetBit(nalu, offset); - m_sps_[sps_id].vui_parameters_present_flag = Parser::GetBit(nalu, offset); - if (m_sps_[sps_id].vui_parameters_present_flag) { + sps_ptr->sps_temporal_mvp_enabled_flag = Parser::GetBit(nalu, offset); + sps_ptr->strong_intra_smoothing_enabled_flag = Parser::GetBit(nalu, offset); + sps_ptr->vui_parameters_present_flag = Parser::GetBit(nalu, offset); + if (sps_ptr->vui_parameters_present_flag) { //vui_parameters() - ParseVui(&m_sps_[sps_id].vui_parameters, m_sps_[sps_id].sps_max_sub_layers_minus1, nalu, size, offset); + ParseVui(&sps_ptr->vui_parameters, sps_ptr->sps_max_sub_layers_minus1, nalu, size, offset); } - m_sps_[sps_id].sps_extension_flag = Parser::GetBit(nalu, offset); + sps_ptr->sps_extension_flag = Parser::GetBit(nalu, offset); #if DBGINFO - PrintSps(&m_sps_[sps_id]); + PrintSps(sps_ptr); #endif // DBGINFO } void HEVCVideoParser::ParsePps(uint8_t *nalu, size_t size) { size_t offset = 0; uint32_t pps_id = Parser::ExpGolomb::ReadUe(nalu, offset); - memset(&m_pps_[pps_id], 0, sizeof(m_pps_[pps_id])); + PpsData *pps_ptr = &m_pps_[pps_id]; + memset(pps_ptr, 0, sizeof(PpsData)); - m_pps_[pps_id].pps_pic_parameter_set_id = pps_id; - m_pps_[pps_id].pps_seq_parameter_set_id = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].dependent_slice_segments_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].output_flag_present_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].num_extra_slice_header_bits = Parser::ReadBits(nalu, offset, 3); - m_pps_[pps_id].sign_data_hiding_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].cabac_init_present_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].num_ref_idx_l0_default_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].num_ref_idx_l1_default_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].init_qp_minus26 = Parser::ExpGolomb::ReadSe(nalu, offset); - m_pps_[pps_id].constrained_intra_pred_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].transform_skip_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].cu_qp_delta_enabled_flag = Parser::GetBit(nalu, offset); - if (m_pps_[pps_id].cu_qp_delta_enabled_flag) { - m_pps_[pps_id].diff_cu_qp_delta_depth = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->pps_pic_parameter_set_id = pps_id; + pps_ptr->pps_seq_parameter_set_id = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->dependent_slice_segments_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->output_flag_present_flag = Parser::GetBit(nalu, offset); + pps_ptr->num_extra_slice_header_bits = Parser::ReadBits(nalu, offset, 3); + pps_ptr->sign_data_hiding_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->cabac_init_present_flag = Parser::GetBit(nalu, offset); + pps_ptr->num_ref_idx_l0_default_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->num_ref_idx_l1_default_active_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->init_qp_minus26 = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->constrained_intra_pred_flag = Parser::GetBit(nalu, offset); + pps_ptr->transform_skip_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->cu_qp_delta_enabled_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->cu_qp_delta_enabled_flag) { + pps_ptr->diff_cu_qp_delta_depth = Parser::ExpGolomb::ReadUe(nalu, offset); } - m_pps_[pps_id].pps_cb_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); - m_pps_[pps_id].pps_cr_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); - m_pps_[pps_id].pps_slice_chroma_qp_offsets_present_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].weighted_pred_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].weighted_bipred_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].transquant_bypass_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].tiles_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].entropy_coding_sync_enabled_flag = Parser::GetBit(nalu, offset); - if (m_pps_[pps_id].tiles_enabled_flag) { - m_pps_[pps_id].num_tile_columns_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].num_tile_rows_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].uniform_spacing_flag = Parser::GetBit(nalu, offset); - if (!m_pps_[pps_id].uniform_spacing_flag) { - for (int i = 0; i < m_pps_[pps_id].num_tile_columns_minus1; i++) { - m_pps_[pps_id].column_width_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->pps_cb_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->pps_cr_qp_offset = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->pps_slice_chroma_qp_offsets_present_flag = Parser::GetBit(nalu, offset); + pps_ptr->weighted_pred_flag = Parser::GetBit(nalu, offset); + pps_ptr->weighted_bipred_flag = Parser::GetBit(nalu, offset); + pps_ptr->transquant_bypass_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->tiles_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->entropy_coding_sync_enabled_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->tiles_enabled_flag) { + pps_ptr->num_tile_columns_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->num_tile_rows_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); + pps_ptr->uniform_spacing_flag = Parser::GetBit(nalu, offset); + if (!pps_ptr->uniform_spacing_flag) { + for (int i = 0; i < pps_ptr->num_tile_columns_minus1; i++) { + pps_ptr->column_width_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); } - for (int i = 0; i < m_pps_[pps_id].num_tile_rows_minus1; i++) { - m_pps_[pps_id].row_height_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + for (int i = 0; i < pps_ptr->num_tile_rows_minus1; i++) { + pps_ptr->row_height_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); } } - m_pps_[pps_id].loop_filter_across_tiles_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->loop_filter_across_tiles_enabled_flag = Parser::GetBit(nalu, offset); } else { - m_pps_[pps_id].loop_filter_across_tiles_enabled_flag = 1; - m_pps_[pps_id].uniform_spacing_flag = 1; + pps_ptr->loop_filter_across_tiles_enabled_flag = 1; + pps_ptr->uniform_spacing_flag = 1; } - m_pps_[pps_id].pps_loop_filter_across_slices_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].deblocking_filter_control_present_flag = Parser::GetBit(nalu, offset); - if (m_pps_[pps_id].deblocking_filter_control_present_flag) { - m_pps_[pps_id].deblocking_filter_override_enabled_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].pps_deblocking_filter_disabled_flag = Parser::GetBit(nalu, offset); - if (!m_pps_[pps_id].pps_deblocking_filter_disabled_flag) { - m_pps_[pps_id].pps_beta_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); - m_pps_[pps_id].pps_tc_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->pps_loop_filter_across_slices_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->deblocking_filter_control_present_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->deblocking_filter_control_present_flag) { + pps_ptr->deblocking_filter_override_enabled_flag = Parser::GetBit(nalu, offset); + pps_ptr->pps_deblocking_filter_disabled_flag = Parser::GetBit(nalu, offset); + if (!pps_ptr->pps_deblocking_filter_disabled_flag) { + pps_ptr->pps_beta_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); + pps_ptr->pps_tc_offset_div2 = Parser::ExpGolomb::ReadSe(nalu, offset); } } - m_pps_[pps_id].pps_scaling_list_data_present_flag = Parser::GetBit(nalu, offset); - if (m_pps_[pps_id].pps_scaling_list_data_present_flag) { - ParseScalingList(&m_pps_[pps_id].scaling_list_data, nalu, size, offset); + pps_ptr->pps_scaling_list_data_present_flag = Parser::GetBit(nalu, offset); + if (pps_ptr->pps_scaling_list_data_present_flag) { + // Set up default values first + SetDefaultScalingList(&pps_ptr->scaling_list_data); + + ParseScalingList(&pps_ptr->scaling_list_data, nalu, size, offset, &m_sps_[pps_ptr->pps_seq_parameter_set_id]); } - m_pps_[pps_id].lists_modification_present_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].log2_parallel_merge_level_minus2 = Parser::ExpGolomb::ReadUe(nalu, offset); - m_pps_[pps_id].slice_segment_header_extension_present_flag = Parser::GetBit(nalu, offset); - m_pps_[pps_id].pps_extension_flag = Parser::GetBit(nalu, offset); + else { + pps_ptr->scaling_list_data = m_sps_[pps_ptr->pps_seq_parameter_set_id].scaling_list_data; + } + 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); #if DBGINFO - PrintPps(&m_pps_[pps_id]); + PrintPps(pps_ptr); #endif // DBGINFO } @@ -907,6 +1013,9 @@ bool HEVCVideoParser::ParseSliceHeader(uint32_t nal_unit_type, uint8_t *nalu, si if (pps_ptr->output_flag_present_flag) { m_sh_->pic_output_flag = Parser::GetBit(nalu, offset); } + else { + m_sh_->pic_output_flag = 1; // default value + } if (sps_ptr->separate_colour_plane_flag) { m_sh_->colour_plane_id = Parser::ReadBits(nalu, offset, 2); } @@ -1057,31 +1166,6 @@ size_t HEVCVideoParser::EBSPtoRBSP(uint8_t *streamBuffer,size_t begin_bytepos, s return end_bytepos - begin_bytepos + reduce_count; } -//size_id = 0 -int scaling_list_default_0 [1][6][16] = {{{16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, - {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, - {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, - {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, - {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}, - {16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16}}}; -//size_id = 1, 2 -int scaling_list_default_1_2 [2][6][64] = {{{16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}}, - {{16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}}}; -//size_id = 3 -int scaling_list_default_3 [1][2][64] = {{{16,16,16,16,16,16,16,16,16,16,17,16,17,16,17,18,17,18,18,17,18,21,19,20,21,20,19,21,24,22,22,24,24,22,22,24,25,25,27,30,27,25,25,29,31,35,35,31,29,36,41,44,41,36,47,54,54,47,65,70,65,88,88,115}, - {16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,18,18,18,18,18,18,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,28,28,28,28,28,28,33,33,33,33,33,41,41,41,41,54,54,54,71,71,91}}}; - - #if DBGINFO void HEVCVideoParser::PrintVps(HEVCVideoParser::VpsData *vps_ptr) { MSG("=== hevc_video_parameter_set_t ==="); @@ -1193,6 +1277,16 @@ void HEVCVideoParser::PrintSps(HEVCVideoParser::SpsData *sps_ptr) { MSG("max_transform_hierarchy_depth_intra = " << sps_ptr->max_transform_hierarchy_depth_intra); MSG("scaling_list_enabled_flag = " << sps_ptr->scaling_list_enabled_flag); MSG("sps_scaling_list_data_present_flag = " << sps_ptr->sps_scaling_list_data_present_flag); + MSG("Scaling list:"); + for (int i = 0; i < H265_SCALING_LIST_SIZE_NUM; i++) { + for (int j = 0; j < H265_SCALING_LIST_NUM; j++) { + MSG_NO_NEWLINE("scaling_list[" << i <<"][" << j << "][]:") + for (int k = 0; k < H265_SCALING_LIST_MAX_I; k++) { + MSG_NO_NEWLINE(" " << sps_ptr->scaling_list_data.scaling_list[i][j][k]); + } + MSG(""); + } + } MSG("amp_enabled_flag = " << sps_ptr->amp_enabled_flag); MSG("sample_adaptive_offset_enabled_flag = " << sps_ptr->sample_adaptive_offset_enabled_flag); @@ -1205,60 +1299,8 @@ void HEVCVideoParser::PrintSps(HEVCVideoParser::SpsData *sps_ptr) { MSG("num_short_term_ref_pic_sets = " << sps_ptr->num_short_term_ref_pic_sets); if (sps_ptr->num_short_term_ref_pic_sets) { - MSG("Short term RPS:"); for(int i = 0; i < sps_ptr->num_short_term_ref_pic_sets; i++) { - /*Todo: MSG("st_rps[%d]: " << i); - MSG("inter_ref_pic_set_prediction_flag = " << sps_ptr->st_rps[i].inter_ref_pic_set_prediction_flag); - MSG("delta_idx_minus1 = " << sps_ptr->st_rps[i].delta_idx_minus1); - MSG("delta_rps_sign = " << sps_ptr->st_rps[i].delta_rps_sign); - MSG("abs_delta_rps_minus1 = " << sps_ptr->st_rps[i].abs_delta_rps_minus1); - MSG("used_by_curr_pic_flag[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].used_by_curr_pic_flag[j]); - } - MSG(""); - MSG("use_delta_flag[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].use_delta_flag[j]); - } - MSG("");*/ - - MSG("num_negative_pics = " << sps_ptr->st_rps[i].num_negative_pics); - MSG("num_positive_pics = " << sps_ptr->st_rps[i].num_positive_pics); - MSG("num_of_pics = " << sps_ptr->st_rps[i].num_of_pics); - MSG("num_of_delta_poc = " << sps_ptr->st_rps[i].num_of_delta_poc); - - MSG_NO_NEWLINE("delta_poc[16]:"); - for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << sps_ptr->st_rps[i].delta_poc[j]); - } - MSG(""); - MSG_NO_NEWLINE("used_by_curr_pic[16]:"); - for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << sps_ptr->st_rps[i].used_by_curr_pic[j]); - } - MSG(""); - - /* Todo MSG("delta_poc_s0_minus1[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].delta_poc_s0_minus1[j]); - } - MSG(""); - MSG("used_by_curr_pic_s0_flag[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].used_by_curr_pic_s0_flag[j]); - } - MSG(""); - MSG("delta_poc_s1_minus1[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].delta_poc_s1_minus1[j]); - } - MSG(""); - MSG("used_by_curr_pic_s1_flag[]: "); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG(" ", sps_ptr->st_rps[i].used_by_curr_pic_s1_flag[j]); - } - MSG("");*/ + PrintRps(&sps_ptr->st_rps[i]); } } @@ -1333,6 +1375,17 @@ void HEVCVideoParser::PrintPps(HEVCVideoParser::PpsData *pps_ptr) { MSG("pps_beta_offset_div2 = " << pps_ptr->pps_beta_offset_div2); MSG("pps_tc_offset_div2 = " << pps_ptr->pps_tc_offset_div2); MSG("pps_scaling_list_data_present_flag = " << pps_ptr->pps_scaling_list_data_present_flag); + MSG("Scaling list:"); + for (int i = 0; i < H265_SCALING_LIST_SIZE_NUM; i++) { + for (int j = 0; j < H265_SCALING_LIST_NUM; j++) { + MSG_NO_NEWLINE("scaling_list[" << i <<"][" << j << "][]:") + for (int k = 0; k < H265_SCALING_LIST_MAX_I; k++) { + MSG_NO_NEWLINE(" " << pps_ptr->scaling_list_data.scaling_list[i][j][k]); + } + MSG(""); + } + } + 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); @@ -1354,59 +1407,8 @@ 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); - MSG("Short term RPS:"); - { - /* Todo: MSG("inter_ref_pic_set_prediction_flag = " << slice_header_ptr->st_rps.inter_ref_pic_set_prediction_flag); - MSG("delta_idx_minus1 = " << slice_header_ptr->st_rps.delta_idx_minus1); - MSG("delta_rps_sign = " << slice_header_ptr->st_rps.delta_rps_sign); - MSG("abs_delta_rps_minus1 = " << slice_header_ptr->st_rps.abs_delta_rps_minus1); - MSG_NO_NEWLINE("used_by_curr_pic_flag[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.used_by_curr_pic_flag[j]); - } - MSG(""); - MSG_NO_NEWLINE("use_delta_flag[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.use_delta_flag[j]); - } - MSG("");*/ - MSG("num_negative_pics = " << slice_header_ptr->st_rps.num_negative_pics); - MSG("num_positive_pics = " << slice_header_ptr->st_rps.num_positive_pics); - MSG("num_of_pics = " << slice_header_ptr->st_rps.num_of_pics); - MSG("num_of_delta_poc = " << slice_header_ptr->st_rps.num_of_delta_poc); + PrintRps(&slice_header_ptr->st_rps); - MSG_NO_NEWLINE("delta_poc[16]:"); - for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.delta_poc[j]); - } - MSG(""); - MSG_NO_NEWLINE("used_by_curr_pic[16]:"); - for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.used_by_curr_pic[j]); - } - MSG(""); - - /* Todo: MSG_NO_NEWLINE("delta_poc_s0_minus1[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.delta_poc_s0_minus1[j]); - } - MSG(""); - MSG_NO_NEWLINE("used_by_curr_pic_s0_flag[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.used_by_curr_pic_s0_flag[j]); - } - MSG(""); - MSG_NO_NEWLINE("delta_poc_s1_minus1[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.delta_poc_s1_minus1[j]); - } - MSG(""); - MSG_NO_NEWLINE("used_by_curr_pic_s1_flag[]:"); - for(int j = 0; j < HEVC_MAX_DPB; j++) { - MSG_NO_NEWLINE(" " << slice_header_ptr->st_rps.used_by_curr_pic_s1_flag[j]); - } - MSG("");*/ - } MSG("num_long_term_sps = " << slice_header_ptr->num_long_term_sps); MSG("num_long_term_pics = " << slice_header_ptr->num_long_term_pics); MSG_NO_NEWLINE("lt_idx_sps[]:"); @@ -1472,4 +1474,58 @@ void HEVCVideoParser::PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slic MSG("slice_segment_header_extension_length = %d " << slice_header_ptr->slice_segment_header_extension_length);*/ MSG(""); } + +void HEVCVideoParser::PrintRps(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); + MSG("delta_rps_sign = " << rps_ptr->delta_rps_sign); + MSG("abs_delta_rps_minus1 = " << rps_ptr->abs_delta_rps_minus1); + MSG_NO_NEWLINE("rps->used_by_curr_pic_flag[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic_flag[j]); + } + MSG(""); + MSG_NO_NEWLINE("use_delta_flag[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->use_delta_flag[j]); + } + MSG(""); + MSG("num_negative_pics = " << rps_ptr->num_negative_pics); + MSG("num_positive_pics = " << rps_ptr->num_positive_pics); + MSG("num_of_pics = " << rps_ptr->num_of_pics); + MSG("num_of_delta_poc = " << rps_ptr->num_of_delta_poc); + + MSG_NO_NEWLINE("delta_poc_s0_minus1[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->delta_poc_s0_minus1[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic_s0_flag[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic_s0_flag[j]); + } + MSG(""); + MSG_NO_NEWLINE("delta_poc_s1_minus1[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->delta_poc_s1_minus1[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic_s1_flag[]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic_s1_flag[j]); + } + MSG(""); + + MSG_NO_NEWLINE("delta_poc[16] (DeltaPocS0 + DeltaPocS1):"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->delta_poc[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic[16] (UsedByCurrPicS0 + UsedByCurrPicS1):"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic[j]); + } + MSG(""); +} #endif // DBGINFO \ No newline at end of file diff --git a/projects/rocdecode/src/parser/hevc_parser.h b/projects/rocdecode/src/parser/hevc_parser.h index 965e5149b9..a66317177c 100644 --- a/projects/rocdecode/src/parser/hevc_parser.h +++ b/projects/rocdecode/src/parser/hevc_parser.h @@ -212,17 +212,28 @@ protected: int32_t scaling_list_dc_coef_minus8[4][6]; //se(v) int32_t scaling_list_delta_coef; //se(v) could have issues...... int32_t scaling_list[H265_SCALING_LIST_SIZE_NUM][H265_SCALING_LIST_NUM][H265_SCALING_LIST_MAX_I]; + int32_t scaling_list_dc_coef[2][6]; // DC coefficient for 16x16 and 32x32 } H265ScalingListData; /*! \brief Structure for Short Term Reference Picture Set */ typedef struct { - int32_t num_negative_pics; - int32_t num_positive_pics; - int32_t num_of_pics; - int32_t num_of_delta_poc; - int32_t delta_poc[16]; - bool used_by_curr_pic[16]; + uint32_t inter_ref_pic_set_prediction_flag; + uint32_t delta_idx_minus1; + uint32_t delta_rps_sign; + uint32_t abs_delta_rps_minus1; + uint32_t used_by_curr_pic_flag[16]; + uint32_t use_delta_flag[16]; + uint32_t num_negative_pics; // NumNegativePics + uint32_t num_positive_pics; // NumPositivePics + uint32_t num_of_pics; + uint32_t num_of_delta_poc; // NumDeltaPocs + uint32_t delta_poc_s0_minus1[16]; + uint32_t used_by_curr_pic_s0_flag[16]; + uint32_t delta_poc_s1_minus1[16]; + uint32_t used_by_curr_pic_s1_flag[16]; + int32_t delta_poc[16]; // DeltaPocS0 + DeltaPocS1 + bool used_by_curr_pic[16]; // UsedByCurrPicS0 + UsedByCurrPicS1 } H265ShortTermRPS; /*! \brief Structure for Long Term Reference Picture Set @@ -388,9 +399,9 @@ protected: uint32_t bit_depth_chroma_minus8; //ue(v) uint32_t log2_max_pic_order_cnt_lsb_minus4; //ue(v) bool sps_sub_layer_ordering_info_present_flag; //u(1) - uint32_t sps_max_dec_pic_buffering_minus1[6]; //ue(v) - uint32_t sps_max_num_reorder_pics[6]; //ue(v) - uint32_t sps_max_latency_increase_plus1[6]; //ue(v) + uint32_t sps_max_dec_pic_buffering_minus1[7]; //ue(v) + uint32_t sps_max_num_reorder_pics[7]; //ue(v) + uint32_t sps_max_latency_increase_plus1[7]; //ue(v) uint32_t log2_min_luma_coding_block_size_minus3; //ue(v) uint32_t log2_diff_max_min_luma_coding_block_size; //ue(v) uint32_t log2_min_transform_block_size_minus2; //ue(v) @@ -658,14 +669,21 @@ protected: */ void ParseHrdParameters(H265HrdParameters *hrd, bool common_inf_present_flag, uint32_t max_num_sub_layers_minus1, uint8_t *nalu, size_t size, size_t &offset); + /*! \brief Function to set the default values to the scaling list + * \param [out] sl_ptr A pointer to the scaling list H265ScalingListData + * \return No return value + */ + void SetDefaultScalingList(H265ScalingListData *sl_ptr); + /*! \brief Function to parse Scaling List - * \param [out] s_data A pointer of H265ScalingListData for the output from the parsed stream + * \param [out] sl_ptr A pointer of H265ScalingListData for the output from the parsed stream * \param [in] data A pointer of uint8_t for the input stream to be parsed * \param [in] size Size of the input stream * \param [in] offset Reference to the offset in the input buffer + * \param [in] sps_ptr Pointer to the current SPS * \return No return value */ - void ParseScalingList(H265ScalingListData * s_data, uint8_t *data, size_t size, size_t &offset); + void ParseScalingList(H265ScalingListData * sl_ptr, uint8_t *data, size_t size, size_t &offset, SpsData *sps_ptr); /*! \brief Function to parse Video Usability Information * \param [out] vui A pointer of H265VuiParameters for the output from the parsed stream @@ -714,6 +732,7 @@ 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); #endif // DBGINFO private: