diff --git a/projects/rocdecode/src/parser/hevc_parser.cpp b/projects/rocdecode/src/parser/hevc_parser.cpp index 3ca7522163..03e7a530a5 100644 --- a/projects/rocdecode/src/parser/hevc_parser.cpp +++ b/projects/rocdecode/src/parser/hevc_parser.cpp @@ -1027,17 +1027,18 @@ void HEVCVideoParser::ParseScalingList(H265ScalingListData * sl_ptr, uint8_t *na } } -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) { - int32_t i = 0; +void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, uint32_t st_rps_idx, uint32_t number_short_term_ref_pic_sets, H265ShortTermRPS rps_ref[], uint8_t *nalu, size_t /*size*/, size_t& offset) { + int i, j; - if (st_rps_idx != 0) { + memset(rps, 0, sizeof(H265ShortTermRPS)); + if (st_rps_idx != 0) { rps->inter_ref_pic_set_prediction_flag = Parser::GetBit(nalu, offset); } 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) { + if (st_rps_idx == number_short_term_ref_pic_sets) { rps->delta_idx_minus1 = Parser::ExpGolomb::ReadUe(nalu, offset); } else { @@ -1045,9 +1046,11 @@ void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_ } 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++) { + int ref_rps_idx = st_rps_idx - (rps->delta_idx_minus1 + 1); // (7-59) + int delta_rps = (1 - 2 * rps->delta_rps_sign) * (rps->abs_delta_rps_minus1 + 1); // (7-60) + + H265ShortTermRPS *ref_rps = &rps_ref[ref_rps_idx]; + for (j = 0; j <= ref_rps->num_of_delta_pocs; 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); @@ -1057,74 +1060,74 @@ void HEVCVideoParser::ParseShortTermRefPicSet(H265ShortTermRPS *rps, int32_t st_ } } - 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 && rps->use_delta_flag[rps_ref[ref_idx].num_negative_pics + j]) { - rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics + j]; + int d_poc; + i = 0; + for (j = ref_rps->num_positive_pics - 1; j >= 0; j--) { + d_poc = ref_rps->delta_poc_s1[j] + delta_rps; + if (d_poc < 0 && rps->use_delta_flag[ref_rps->num_negative_pics + j]) { + rps->delta_poc_s0[i] = d_poc; + rps->used_by_curr_pic_s0[i++] = rps->used_by_curr_pic_flag[ref_rps->num_negative_pics + j]; } } - 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++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; + if (delta_rps < 0 && rps->use_delta_flag[ref_rps->num_of_delta_pocs]) { + rps->delta_poc_s0[i] = delta_rps; + rps->used_by_curr_pic_s0[i++] = rps->used_by_curr_pic_flag[ref_rps->num_of_delta_pocs]; } - 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 && rps->use_delta_flag[j]) { - rps->delta_poc[i]=delta_poc; - rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[j]; + for (j = 0; j < ref_rps->num_negative_pics; j++) { + d_poc = ref_rps->delta_poc_s0[j] + delta_rps; + if (d_poc < 0 && rps->use_delta_flag[j]) { + rps->delta_poc_s0[i] = d_poc; + rps->used_by_curr_pic_s0[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 && rps->use_delta_flag[j]) { - rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[j]; + + i = 0; + for (j = ref_rps->num_negative_pics - 1; j >= 0; j--) { + d_poc = ref_rps->delta_poc_s0[j] + delta_rps; + if (d_poc > 0 && rps->use_delta_flag[j]) { + rps->delta_poc_s1[i] = d_poc; + rps->used_by_curr_pic_s1[i++] = rps->used_by_curr_pic_flag[j]; } } - 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++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_of_pics]; + if (delta_rps > 0 && rps->use_delta_flag[ref_rps->num_of_delta_pocs]) { + rps->delta_poc_s1[i] = delta_rps; + rps->used_by_curr_pic_s1[i++] = rps->used_by_curr_pic_flag[ref_rps->num_of_delta_pocs]; } - 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 && rps->use_delta_flag[rps_ref[ref_idx].num_negative_pics+j]) { - rps->delta_poc[i] = delta_poc; - rps->used_by_curr_pic[i++] = rps->used_by_curr_pic_flag[rps_ref[ref_idx].num_negative_pics+j]; + + for (j = 0; j < ref_rps->num_positive_pics; j++) { + d_poc = ref_rps->delta_poc_s1[j] + delta_rps; + if (d_poc > 0 && rps->use_delta_flag[ref_rps->num_negative_pics + j]) { + rps->delta_poc_s1[i] = d_poc; + rps->used_by_curr_pic_s1[i++] = rps->used_by_curr_pic_flag[ref_rps->num_negative_pics + j]; } } - rps->num_positive_pics = i - rps->num_negative_pics ; - rps->num_of_delta_poc = rps_ref[ref_idx].num_negative_pics + rps_ref[ref_idx].num_positive_pics; - rps->num_of_pics = i; - } - else { + rps->num_positive_pics = i; + rps->num_of_delta_pocs = rps->num_negative_pics + rps->num_positive_pics; + } else { rps->num_negative_pics = Parser::ExpGolomb::ReadUe(nalu, offset); rps->num_positive_pics = Parser::ExpGolomb::ReadUe(nalu, offset); - int32_t prev = 0; - int32_t poc; - // DeltaPocS0, UsedByCurrPicS0 - for (int j = 0; j < rps->num_negative_pics; j++) { - 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; // 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 + rps->num_of_delta_pocs = rps->num_negative_pics + rps->num_positive_pics; + + for (i = 0; i < rps->num_negative_pics; i++) { + rps->delta_poc_s0_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + if (i == 0) { + rps->delta_poc_s0[i] = -(rps->delta_poc_s0_minus1[i] + 1); + } else { + rps->delta_poc_s0[i] = rps->delta_poc_s0[i - 1] - (rps->delta_poc_s0_minus1[i] + 1); + } + rps->used_by_curr_pic_s0[i] = Parser::GetBit(nalu, offset); } - prev = 0; - // 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 + 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 + + for (i = 0; i < rps->num_positive_pics; i++) { + rps->delta_poc_s1_minus1[i] = Parser::ExpGolomb::ReadUe(nalu, offset); + if (i == 0) { + rps->delta_poc_s1[i] = rps->delta_poc_s1_minus1[i] + 1; + } else { + rps->delta_poc_s1[i] = rps->delta_poc_s1[i - 1] + (rps->delta_poc_s1_minus1[i] + 1); + } + rps->used_by_curr_pic_s1[i] = Parser::GetBit(nalu, offset); } - 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; } } @@ -1735,9 +1738,13 @@ bool HEVCVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size) { // Calculate NumPicTotalCurr 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]) { + for (int i = 0; i < st_rps_ptr->num_negative_pics; i++) { + if (st_rps_ptr->used_by_curr_pic_s0[i]) { + num_pic_total_curr_++; + } + } + for (int i = 0; i < st_rps_ptr->num_positive_pics; i++) { + if (st_rps_ptr->used_by_curr_pic_s1[i]) { num_pic_total_curr_++; } } @@ -2009,22 +2016,21 @@ void HEVCVideoParser::DecodeRps() { else { H265ShortTermRPS *rps_ptr = &m_sh_->st_rps; for (i = 0, j = 0, k = 0; i < rps_ptr->num_negative_pics; i++) { - if (rps_ptr->used_by_curr_pic[i]) { // UsedByCurrPicS0 - poc_st_curr_before_[j++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc[i]; // DeltaPocS0 + if (rps_ptr->used_by_curr_pic_s0[i]) { + poc_st_curr_before_[j++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc_s0[i]; } else { - poc_st_foll_[k++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc[i]; + poc_st_foll_[k++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc_s0[i]; } } num_poc_st_curr_before_ = j; - // UsedByCurrPicS1 follows UsedByCurrPicS0 in used_by_curr_pic. DeltaPocS1 follows DeltaPocS0 in delta_poc. - for (j = 0; i < rps_ptr->num_of_delta_poc; i++ ) { - if (rps_ptr->used_by_curr_pic[i]) { // UsedByCurrPicS1 - poc_st_curr_after_[j++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc[i]; // DeltaPocS1 + for (i = 0, j = 0; i < rps_ptr->num_positive_pics; i++ ) { + if (rps_ptr->used_by_curr_pic_s1[i]) { + poc_st_curr_after_[j++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc_s1[i]; } else { - poc_st_foll_[k++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc[i]; // DeltaPocS1 + poc_st_foll_[k++] = curr_pic_info_.pic_order_cnt + rps_ptr->delta_poc_s1[i]; } } num_poc_st_curr_after_ = j; @@ -2337,8 +2343,16 @@ int HEVCVideoParser::FindFreeBufAndMark() { } dpb_buffer_.dpb_fullness++; - // Skip additional bumping after the current picture is added to DPB. This avoids immediate wait for - // decode completion of the current frame in certain cases. + SpsData *sps_ptr = &m_sps_[m_active_sps_id_]; + uint32_t highest_tid = sps_ptr->sps_max_sub_layers_minus1; // HighestTid + uint32_t max_num_reorder_pics = sps_ptr->sps_max_num_reorder_pics[highest_tid]; + + while (dpb_buffer_.num_needed_for_output > max_num_reorder_pics) { + if (BumpPicFromDpb() != PARSER_OK) { + return PARSER_FAIL; + } + } + // Skip SpsMaxLatencyPictures check as SpsMaxLatencyPictures >= sps_max_num_reorder_pics. return PARSER_OK; @@ -2762,8 +2776,7 @@ void HEVCVideoParser::PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr) { 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("num_of_delta_pocs = " << rps_ptr->num_of_delta_pocs); MSG_NO_NEWLINE("delta_poc_s0_minus1[]:"); for(int j = 0; j < 16; j++) { @@ -2786,14 +2799,24 @@ void HEVCVideoParser::PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr) { } MSG(""); - MSG_NO_NEWLINE("delta_poc[16] (DeltaPocS0 + DeltaPocS1):"); + MSG_NO_NEWLINE("delta_poc_s0[16]:"); for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << rps_ptr->delta_poc[j]); + MSG_NO_NEWLINE(" " << rps_ptr->delta_poc_s0[j]); } MSG(""); - MSG_NO_NEWLINE("used_by_curr_pic[16] (UsedByCurrPicS0 + UsedByCurrPicS1):"); + MSG_NO_NEWLINE("delta_poc_s1[16]:"); for(int j = 0; j < 16; j++) { - MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic[j]); + MSG_NO_NEWLINE(" " << rps_ptr->delta_poc_s1[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic_s0[16]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic_s0[j]); + } + MSG(""); + MSG_NO_NEWLINE("used_by_curr_pic_s1[16]:"); + for(int j = 0; j < 16; j++) { + MSG_NO_NEWLINE(" " << rps_ptr->used_by_curr_pic_s1[j]); } MSG(""); } @@ -2812,15 +2835,4 @@ void HEVCVideoParser::PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_p } MSG(""); } - -void HEVCVideoParser::PrintSeiMessage(HEVCVideoParser::SeiMessageData *sei_message_ptr) { - MSG("=== hevc_sei_message_info ==="); - MSG("payload_type = " << sei_message_ptr->payload_type); - MSG("payload_size = " << sei_message_ptr->payload_size); - MSG_NO_NEWLINE("reserved[3]: "); - for(int i = 0; i < 3; i++) { - MSG_NO_NEWLINE(" " << sei_message_ptr->reserved[i]); - } - 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 54f6beadbf..eea9a5c76c 100644 --- a/projects/rocdecode/src/parser/hevc_parser.h +++ b/projects/rocdecode/src/parser/hevc_parser.h @@ -224,7 +224,7 @@ protected: bool scaling_list_pred_mode_flag[4][6]; //u(1) uint32_t scaling_list_pred_matrix_id_delta[4][6]; //ue(v) 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_delta_coef; //se(v) 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; @@ -232,23 +232,26 @@ protected: /*! \brief Structure for Short Term Reference Picture Set */ typedef struct { - 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; + uint8_t inter_ref_pic_set_prediction_flag; + uint32_t delta_idx_minus1; + uint8_t delta_rps_sign; + uint32_t abs_delta_rps_minus1; + uint8_t used_by_curr_pic_flag[HEVC_MAX_DPB_FRAMES]; + uint8_t use_delta_flag[HEVC_MAX_DPB_FRAMES]; + + uint32_t delta_poc_s0_minus1[HEVC_MAX_DPB_FRAMES]; + uint8_t used_by_curr_pic_s0_flag[HEVC_MAX_DPB_FRAMES]; + uint32_t delta_poc_s1_minus1[HEVC_MAX_DPB_FRAMES]; + uint8_t used_by_curr_pic_s1_flag[HEVC_MAX_DPB_FRAMES]; + + uint32_t num_negative_pics; // NumNegativePics + uint32_t num_positive_pics; // NumPositivePics + uint32_t num_of_delta_pocs; // NumDeltaPocs + uint8_t used_by_curr_pic_s0[HEVC_MAX_DPB_FRAMES]; // UsedByCurrPicS0 + uint8_t used_by_curr_pic_s1[HEVC_MAX_DPB_FRAMES]; // UsedByCurrPicS1 + int32_t delta_poc_s0[HEVC_MAX_DPB_FRAMES]; // DeltaPocS0 + int32_t delta_poc_s1[HEVC_MAX_DPB_FRAMES]; // DeltaPocS1 +} H265ShortTermRPS; /*! \brief Structure for Long Term Reference Picture Set */ @@ -824,7 +827,7 @@ protected: /*! \brief Function to parse Short Term Reference Picture Set * \param [out] rps A pointer of H265ShortTermRPS for the output from the parsed stream - * \param [in] st_rps_idx Input of int32_t - specifies the index in the RPS buffer + * \param [in] st_rps_idx specifies the index in the RPS buffer * \param [in] num_short_term_ref_pic_sets Specifies the count of Short Term RPS in uint32_t * \param [in] rps_ref A reference of H265ShortTermRPS to the RPS buffer * \param [in] data A pointer of uint8_t for the input stream to be parsed @@ -832,7 +835,7 @@ 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, uint32_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 @@ -917,7 +920,6 @@ protected: void PrintSliceSegHeader(HEVCVideoParser::SliceHeaderData *slice_header_ptr); void PrintStRps(HEVCVideoParser::H265ShortTermRPS *rps_ptr); void PrintLtRefInfo(HEVCVideoParser::H265LongTermRPS *lt_info_ptr); - void PrintSeiMessage(HEVCVideoParser::SeiMessageData *sei_message_ptr); #endif // DBGINFO private: