rocDecode: Added decode buffer pool implementation for AVC and HEVC. (#355)

* * rocDecode: Initial check in for decode buffer pool.

* * rocDecode: All 135 streams pass.

* * rocDecode: Fixed a build error in debug mode.

* * rocDecode/HEVC: Removed two workaround in HEVC DPB management, after decode buffer pool implementa
tion.
 - WR 1: Conditional bumping (when max_num_reorder_pics > 0) to avoid synchronous job submission in
C.5.2.3.
 - WR 2: Add two more buffers in DPB to avoid buffer over-writing.

* * rocDecode/HEVC: Added display delay feature.

* * rocDecode/HEVC: Fixed the -z option issue within the context of the new decode buffer pool implementation.

* * rocDecode/HEVC: Removed redundent code.

* * rocDecode/AVC: Added decode buffer pool implementation for AVC.

* * rocDecode: Added a few changes.
 - Added display delay feature to AVC.
 - Removed a workaround for AVC: AVC_MAX_DPB_FRAMES was increased to 18. Now it is back to 16.
 - Removed a workaround for AVC: increased DPB buffer size by 2. Now it is back to normal.
 - Code format changes for HEVC.

* * rocDecode/AVC: Fixed the -z option issue within the context of the new decode buffer pool implementation.

* * rocDecode: Merged OutputDecodedPictures() method to upper class RocVideoParser.

* * rocDecode: Code cleanup. No functional changes.

* * rocDecode: Made decode buffer pool size adaptive.
 - Removed the hard coded decode buffer pool size set in the decoder.
 - Exposed the display delay parameter from RocVideoDecoder class to the user.
 - Now the decoder buffer pool size is determined from the DPB buffer size and display delay parameter.

* * rocDecode: Several changes based on code review.
 - Merged decode and display use status into one parameter.
 - Removed the surface index from DecodeFrameBuffer, which is now implicitly referred by the array index.
 - Changed a function name for better clarity.

* * rocDecode: Added a comment.

[ROCm/rocdecode commit: 61c8661b9c]
This commit is contained in:
jeffqjiangNew
2024-05-31 13:14:02 -04:00
committed by GitHub
parent 4a6e9d709b
commit 3230cca447
11 changed files with 418 additions and 179 deletions
+171 -80
View File
@@ -78,9 +78,6 @@ rocDecStatus HevcVideoParser::UnInitialize() {
rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
if (p_data->payload && p_data->payload_size) {
// Clear DPB output/display buffer number
dpb_buffer_.num_output_pics = 0;
if (ParsePictureData(p_data->payload, p_data->payload_size) != PARSER_OK) {
ERR(STR("Parser failed!"));
return ROCDEC_RUNTIME_ERROR;
@@ -111,8 +108,8 @@ rocDecStatus HevcVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
}
// Output decoded pictures from DPB if any are ready
if (pfn_display_picture_cb_ && dpb_buffer_.num_output_pics > 0) {
if (OutputDecodedPictures() != PARSER_OK) {
if (pfn_display_picture_cb_ && num_output_pics_ > 0) {
if (OutputDecodedPictures(false) != PARSER_OK) {
return ROCDEC_RUNTIME_ERROR;
}
}
@@ -144,7 +141,7 @@ int HevcVideoParser::FillSeqCallbackFn(HevcSeqParamSet* sps_data) {
video_format_params_.progressive_sequence = 0;
else // default value
video_format_params_.progressive_sequence = 1;
video_format_params_.min_num_decode_surfaces = dpb_buffer_.dpb_size;
video_format_params_.min_num_decode_surfaces = dec_buf_pool_size_;
video_format_params_.coded_width = sps_data->pic_width_in_luma_samples;
video_format_params_.coded_height = sps_data->pic_height_in_luma_samples;
video_format_params_.chroma_format = static_cast<rocDecVideoChromaFormat>(sps_data->chroma_format_idc);
@@ -237,7 +234,7 @@ void HevcVideoParser::SendSeiMsgPayload() {
sei_message_info_params_.sei_message_count = sei_message_count_;
sei_message_info_params_.sei_message = sei_message_list_.data();
sei_message_info_params_.sei_data = (void*)sei_payload_buf_;
sei_message_info_params_.picIdx = curr_pic_info_.pic_idx;
sei_message_info_params_.picIdx = curr_pic_info_.dec_buf_idx;
// callback function with RocdecSeiMessageInfo params filled out
if (pfn_get_sei_message_cb_) pfn_get_sei_message_cb_(parser_params_.user_data, &sei_message_info_params_);
@@ -251,7 +248,7 @@ int HevcVideoParser::SendPicForDecode() {
dec_pic_params_.pic_width = sps_ptr->pic_width_in_luma_samples;
dec_pic_params_.pic_height = sps_ptr->pic_height_in_luma_samples;
dec_pic_params_.curr_pic_idx = curr_pic_info_.pic_idx;
dec_pic_params_.curr_pic_idx = curr_pic_info_.dec_buf_idx;
dec_pic_params_.field_pic_flag = sps_ptr->profile_tier_level.general_interlaced_source_flag;
dec_pic_params_.bottom_field_flag = 0; // For now. Need to parse VUI/SEI pic_timing()
dec_pic_params_.second_field = 0; // For now. Need to parse VUI/SEI pic_timing()
@@ -270,14 +267,14 @@ int HevcVideoParser::SendPicForDecode() {
RocdecHevcPicParams *pic_param_ptr = &dec_pic_params_.pic_params.hevc;
// Current picture
pic_param_ptr->curr_pic.pic_idx = curr_pic_info_.pic_idx;
pic_param_ptr->curr_pic.pic_idx = curr_pic_info_.dec_buf_idx;
pic_param_ptr->curr_pic.poc = curr_pic_info_.pic_order_cnt;
// Reference pictures
ref_idx = 0;
for (i = 0; i < num_poc_st_curr_before_; i++) {
buf_idx = ref_pic_set_st_curr_before_[i]; // buffer index in DPB
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].pic_idx;
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].dec_buf_idx;
pic_param_ptr->ref_frames[ref_idx].poc = dpb_buffer_.frame_buffer_list[buf_idx].pic_order_cnt;
pic_param_ptr->ref_frames[ref_idx].flags = 0; // assume frame picture for now
pic_param_ptr->ref_frames[ref_idx].flags |= RocdecHevcPicture_RPS_ST_CURR_BEFORE;
@@ -286,7 +283,7 @@ int HevcVideoParser::SendPicForDecode() {
for (i = 0; i < num_poc_st_curr_after_; i++) {
buf_idx = ref_pic_set_st_curr_after_[i]; // buffer index in DPB
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].pic_idx;
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].dec_buf_idx;
pic_param_ptr->ref_frames[ref_idx].poc = dpb_buffer_.frame_buffer_list[buf_idx].pic_order_cnt;
pic_param_ptr->ref_frames[ref_idx].flags = 0; // assume frame picture for now
pic_param_ptr->ref_frames[ref_idx].flags |= RocdecHevcPicture_RPS_ST_CURR_AFTER;
@@ -295,7 +292,7 @@ int HevcVideoParser::SendPicForDecode() {
for (i = 0; i < num_poc_lt_curr_; i++) {
buf_idx = ref_pic_set_lt_curr_[i]; // buffer index in DPB
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].pic_idx;
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].dec_buf_idx;
pic_param_ptr->ref_frames[ref_idx].poc = dpb_buffer_.frame_buffer_list[buf_idx].pic_order_cnt;
pic_param_ptr->ref_frames[ref_idx].flags = 0; // assume frame picture for now
pic_param_ptr->ref_frames[ref_idx].flags |= RocdecHevcPicture_LONG_TERM_REFERENCE | RocdecHevcPicture_RPS_LT_CURR;
@@ -304,7 +301,7 @@ int HevcVideoParser::SendPicForDecode() {
for (i = 0; i < num_poc_st_foll_; i++) {
buf_idx = ref_pic_set_st_foll_[i]; // buffer index in DPB
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].pic_idx;
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].dec_buf_idx;
pic_param_ptr->ref_frames[ref_idx].poc = dpb_buffer_.frame_buffer_list[buf_idx].pic_order_cnt;
pic_param_ptr->ref_frames[ref_idx].flags = 0; // assume frame picture for now
ref_idx++;
@@ -312,7 +309,7 @@ int HevcVideoParser::SendPicForDecode() {
for (i = 0; i < num_poc_lt_foll_; i++) {
buf_idx = ref_pic_set_lt_foll_[i]; // buffer index in DPB
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].pic_idx;
pic_param_ptr->ref_frames[ref_idx].pic_idx = dpb_buffer_.frame_buffer_list[buf_idx].dec_buf_idx;
pic_param_ptr->ref_frames[ref_idx].poc = dpb_buffer_.frame_buffer_list[buf_idx].pic_order_cnt;
pic_param_ptr->ref_frames[ref_idx].flags = 0; // assume frame picture for now
ref_idx++;
@@ -424,8 +421,9 @@ int HevcVideoParser::SendPicForDecode() {
if (p_slice_header->slice_type != HEVC_SLICE_TYPE_I) {
for (i = 0; i <= p_slice_header->num_ref_idx_l0_active_minus1; i++) {
int idx = p_slice_info->ref_pic_list_0_[i]; // pic_idx of the ref pic
int dec_buf_idx = dpb_buffer_.frame_buffer_list[idx].dec_buf_idx;
for (j = 0; j < 15; j++) {
if (pic_param_ptr->ref_frames[j].pic_idx == idx) {
if (pic_param_ptr->ref_frames[j].pic_idx == dec_buf_idx) {
break;
}
}
@@ -440,8 +438,9 @@ int HevcVideoParser::SendPicForDecode() {
if (p_slice_header->slice_type == HEVC_SLICE_TYPE_B) {
for (i = 0; i <= p_slice_header->num_ref_idx_l1_active_minus1; i++) {
int idx = p_slice_info->ref_pic_list_1_[i]; // pic_idx of the ref pic
int dec_buf_idx = dpb_buffer_.frame_buffer_list[idx].dec_buf_idx;
for (j = 0; j < 15; j++) {
if (pic_param_ptr->ref_frames[j].pic_idx == idx) {
if (pic_param_ptr->ref_frames[j].pic_idx == dec_buf_idx) {
break;
}
}
@@ -532,6 +531,10 @@ int HevcVideoParser::SendPicForDecode() {
}
}
#if DBGINFO
PrintVappiBufInfo();
#endif // DBGINFO
if (pfn_decode_picture_cb_(parser_params_.user_data, &dec_pic_params_) == 0) {
ERR("Decode error occurred.");
return PARSER_FAIL;
@@ -540,20 +543,6 @@ int HevcVideoParser::SendPicForDecode() {
}
}
int HevcVideoParser::OutputDecodedPictures() {
RocdecParserDispInfo disp_info = {0};
disp_info.progressive_frame = m_sps_[m_active_sps_id_].profile_tier_level.general_progressive_source_flag;
disp_info.top_field_first = 1;
for (int i = 0; i < dpb_buffer_.num_output_pics; i++) {
disp_info.picture_index = dpb_buffer_.frame_buffer_list[dpb_buffer_.output_pic_list[i]].pic_idx;
pfn_display_picture_cb_(parser_params_.user_data, &disp_info);
}
dpb_buffer_.num_output_pics = 0;
return PARSER_OK;
}
ParserResult HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t pic_data_size) {
ParserResult ret = PARSER_OK;
ParserResult ret2;
@@ -667,6 +656,11 @@ ParserResult HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t
// Get POC. 8.3.1.
CalculateCurrPoc();
// Locate a free buffer for the current picutre in decode buffer pool before output picture marking (C.5.2.2)
if (FindFreeInDecBufPool() != PARSER_OK) {
return PARSER_FAIL;
}
// Decode RPS. 8.3.2.
DecodeRps();
}
@@ -683,9 +677,13 @@ ParserResult HevcVideoParser::ParsePictureData(const uint8_t* p_stream, uint32_t
}
// C.5.2.3. Find a free buffer in DPB and mark as used. (After 8.3.2.)
if (FindFreeBufAndMark() != PARSER_OK) {
if (FindFreeInDpbAndMark() != PARSER_OK) {
return PARSER_FAIL;
}
#if DBGINFO
PrintDpb();
#endif // DBGINFO
}
num_slices_++;
break;
@@ -1552,8 +1550,8 @@ ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcS
if (m_active_sps_id_ != pps_ptr->pps_seq_parameter_set_id) {
m_active_sps_id_ = pps_ptr->pps_seq_parameter_set_id;
sps_ptr = &m_sps_[m_active_sps_id_];
// Re-set DPB size. We add 2 addition buffers to avoid overwritting buffer needed for output in certain cases.
dpb_buffer_.dpb_size = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1] + 3;
// Re-set DPB size.
dpb_buffer_.dpb_size = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1] + 1;
dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > HEVC_MAX_DPB_FRAMES ? HEVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size;
new_sps_activated_ = true; // Note: clear this flag after the actions are taken.
}
@@ -1573,12 +1571,17 @@ ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcS
pic_width_ = sps_ptr->pic_width_in_luma_samples;
pic_height_ = sps_ptr->pic_height_in_luma_samples;
// Take care of the case where a new SPS replaces the old SPS with the same id but with different dimensions
// Re-set DPB size. We add 2 addition buffers to avoid overwritting buffer needed for output in certain cases.
dpb_buffer_.dpb_size = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1] + 3;
// Re-set DPB size.
dpb_buffer_.dpb_size = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1] + 1;
dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > HEVC_MAX_DPB_FRAMES ? HEVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size;
new_sps_activated_ = true; // Note: clear this flag after the actions are taken.
}
// Check and adjust decode buffer pool size if needed
if (new_sps_activated_) {
CheckAndAdjustDecBufPoolSize(dpb_buffer_.dpb_size);
}
// Set frame rate if available
if (new_sps_activated_) {
if (m_vps_[m_active_vps_id_].vps_timing_info_present_flag) {
@@ -2130,25 +2133,23 @@ void HevcVideoParser::InitDpb() {
dpb_buffer_.frame_buffer_list[i].pic_idx = i;
dpb_buffer_.frame_buffer_list[i].is_reference = kUnusedForReference;
dpb_buffer_.frame_buffer_list[i].pic_output_flag = 0;
dpb_buffer_.frame_buffer_list[i].use_status = 0;
dpb_buffer_.output_pic_list[i] = 0xFF;
dpb_buffer_.frame_buffer_list[i].use_status = kNotUsed;
}
dpb_buffer_.dpb_size = 0;
dpb_buffer_.dpb_fullness = 0;
dpb_buffer_.num_pics_needed_for_output = 0;
dpb_buffer_.num_output_pics = 0;
}
void HevcVideoParser::EmptyDpb() {
for (int i = 0; i < HEVC_MAX_DPB_FRAMES; i++) {
dpb_buffer_.frame_buffer_list[i].is_reference = kUnusedForReference;
dpb_buffer_.frame_buffer_list[i].pic_output_flag = 0;
dpb_buffer_.frame_buffer_list[i].use_status = 0;
dpb_buffer_.output_pic_list[i] = 0xFF;
dpb_buffer_.frame_buffer_list[i].use_status = kNotUsed;
decode_buffer_pool_[dpb_buffer_.frame_buffer_list[i].dec_buf_idx].use_status = kNotUsed;
}
dpb_buffer_.dpb_fullness = 0;
dpb_buffer_.num_pics_needed_for_output = 0;
dpb_buffer_.num_output_pics = 0;
num_output_pics_ = 0;
}
int HevcVideoParser::FlushDpb() {
@@ -2159,12 +2160,13 @@ int HevcVideoParser::FlushDpb() {
return PARSER_FAIL;
}
}
if (pfn_display_picture_cb_ && dpb_buffer_.num_output_pics > 0) {
if (OutputDecodedPictures() != PARSER_OK) {
return PARSER_FAIL;
}
}
if (pfn_display_picture_cb_ && num_output_pics_ > 0) {
if (OutputDecodedPictures(true) != PARSER_OK) {
return PARSER_FAIL;
}
}
return PARSER_OK;
}
@@ -2185,11 +2187,16 @@ int HevcVideoParser::MarkOutputPictures() {
}
}
// We can still have remaining undisplayed frames due to display delay feature
if (num_output_pics_) {
OutputDecodedPictures(true);
}
EmptyDpb();
} else {
for (i = 0; i < HEVC_MAX_DPB_FRAMES; i++) {
if (dpb_buffer_.frame_buffer_list[i].is_reference == kUnusedForReference && dpb_buffer_.frame_buffer_list[i].pic_output_flag == 0 && dpb_buffer_.frame_buffer_list[i].use_status) {
dpb_buffer_.frame_buffer_list[i].use_status = 0;
dpb_buffer_.frame_buffer_list[i].use_status = kNotUsed;
decode_buffer_pool_[dpb_buffer_.frame_buffer_list[i].dec_buf_idx].use_status &= ~kFrameUsedForDecode;
if (dpb_buffer_.dpb_fullness > 0) {
dpb_buffer_.dpb_fullness--;
} else {
@@ -2222,27 +2229,34 @@ int HevcVideoParser::MarkOutputPictures() {
return PARSER_OK;
}
int HevcVideoParser::FindFreeBufAndMark() {
ParserResult HevcVideoParser::FindFreeInDecBufPool() {
int dec_buf_index;
// Find a free buffer in decode buffer pool
for (dec_buf_index = 0; dec_buf_index < dec_buf_pool_size_; dec_buf_index++) {
if (decode_buffer_pool_[dec_buf_index].use_status == kNotUsed) {
break;
}
}
if (dec_buf_index == dec_buf_pool_size_) {
ERR("Could not find a free buffer in decode buffer pool.");
return PARSER_NOT_FOUND;
}
curr_pic_info_.dec_buf_idx = dec_buf_index;
return PARSER_OK;
}
ParserResult HevcVideoParser::FindFreeInDpbAndMark() {
int i, j;
// Look for an empty buffer with longest decode history (lowest decode count)
// Look for an empty buffer in DPB with longest decode history (lowest decode count)
uint32_t min_decode_order_count = 0xFFFFFFFF;
int index = dpb_buffer_.dpb_size;
for (i = 0; i < dpb_buffer_.dpb_size; i++) {
if (dpb_buffer_.frame_buffer_list[i].use_status == 0) {
if (dpb_buffer_.frame_buffer_list[i].use_status == kNotUsed) {
if (dpb_buffer_.frame_buffer_list[i].decode_order_count < min_decode_order_count) {
// Check if this picture has been bumped to the output/display list. If yes, skip it because we do not want to
// decode the current picture into any buffers in the output list
bool is_in_output_list = false;
for (j = 0; j < dpb_buffer_.num_output_pics; j++) {
if (dpb_buffer_.output_pic_list[j] == i) {
is_in_output_list = true;
}
}
if (!is_in_output_list) {
min_decode_order_count = dpb_buffer_.frame_buffer_list[i].decode_order_count;
index = i;
}
min_decode_order_count = dpb_buffer_.frame_buffer_list[i].decode_order_count;
index = i;
}
}
}
@@ -2254,6 +2268,7 @@ int HevcVideoParser::FindFreeBufAndMark() {
curr_pic_info_.pic_idx = index;
curr_pic_info_.is_reference = kUsedForShortTerm;
// dpb_buffer_.frame_buffer_list[i].pic_idx is already set in InitDpb().
dpb_buffer_.frame_buffer_list[index].dec_buf_idx = curr_pic_info_.dec_buf_idx;
dpb_buffer_.frame_buffer_list[index].pic_order_cnt = curr_pic_info_.pic_order_cnt;
dpb_buffer_.frame_buffer_list[index].prev_poc_lsb = curr_pic_info_.prev_poc_lsb;
dpb_buffer_.frame_buffer_list[index].prev_poc_msb = curr_pic_info_.prev_poc_msb;
@@ -2261,19 +2276,25 @@ int HevcVideoParser::FindFreeBufAndMark() {
dpb_buffer_.frame_buffer_list[index].decode_order_count = curr_pic_info_.decode_order_count;
dpb_buffer_.frame_buffer_list[index].pic_output_flag = curr_pic_info_.pic_output_flag;
dpb_buffer_.frame_buffer_list[index].is_reference = kUsedForShortTerm;
dpb_buffer_.frame_buffer_list[index].use_status = 3;
dpb_buffer_.frame_buffer_list[index].use_status = kFrameUsedForDecode;
if (dpb_buffer_.frame_buffer_list[index].pic_output_flag) {
dpb_buffer_.num_pics_needed_for_output++;
}
dpb_buffer_.dpb_fullness++;
// Mark as used in decode buffer pool
decode_buffer_pool_[curr_pic_info_.dec_buf_idx].use_status |= kFrameUsedForDecode;
if (pfn_display_picture_cb_ && curr_pic_info_.pic_output_flag) {
decode_buffer_pool_[curr_pic_info_.dec_buf_idx].use_status |= kFrameUsedForDisplay;
}
decode_buffer_pool_[curr_pic_info_.dec_buf_idx].pic_order_cnt = curr_pic_info_.pic_order_cnt;
HevcSeqParamSet *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];
// Conditional bumping (when max_num_reorder_pics > 0) to avoid synchronous job submission while keeping in conformance with the spec.
while (max_num_reorder_pics > 0 && dpb_buffer_.num_pics_needed_for_output > max_num_reorder_pics) {
while ( dpb_buffer_.num_pics_needed_for_output > max_num_reorder_pics) {
if (BumpPicFromDpb() != PARSER_OK) {
return PARSER_FAIL;
}
@@ -2310,19 +2331,22 @@ int HevcVideoParser::BumpPicFromDpb() {
// If it is not used for reference, empty it.
if (dpb_buffer_.frame_buffer_list[min_poc_pic_idx].is_reference == kUnusedForReference) {
dpb_buffer_.frame_buffer_list[min_poc_pic_idx].use_status = 0;
dpb_buffer_.frame_buffer_list[min_poc_pic_idx].use_status = kNotUsed;
decode_buffer_pool_[dpb_buffer_.frame_buffer_list[min_poc_pic_idx].dec_buf_idx].use_status &= ~kFrameUsedForDecode;
if (dpb_buffer_.dpb_fullness > 0 ) {
dpb_buffer_.dpb_fullness--;
}
}
// Insert into output/display picture list
if (dpb_buffer_.num_output_pics >= HEVC_MAX_DPB_FRAMES) {
ERR("Error! DPB output buffer list overflow!");
return PARSER_OUT_OF_RANGE;
} else {
dpb_buffer_.output_pic_list[dpb_buffer_.num_output_pics] = min_poc_pic_idx;
dpb_buffer_.num_output_pics++;
if (pfn_display_picture_cb_) {
if (num_output_pics_ >= dec_buf_pool_size_) {
ERR("Error! Decode buffer pool overflow!");
return PARSER_OUT_OF_RANGE;
} else {
output_pic_list_[num_output_pics_] = dpb_buffer_.frame_buffer_list[min_poc_pic_idx].dec_buf_idx;
num_output_pics_++;
}
}
return PARSER_OK;
@@ -2630,7 +2654,7 @@ void HevcVideoParser::PrintSliceSegHeader(HevcSliceSegHeader *slice_header_ptr)
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("cu_chroma_qp_offset_enabled_flag = " << static_cast<uint32_t>(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);
@@ -2644,18 +2668,18 @@ void HevcVideoParser::PrintSliceSegHeader(HevcSliceSegHeader *slice_header_ptr)
void HevcVideoParser::PrintStRps(HevcShortTermRps *rps_ptr) {
MSG("==== Short-term reference picture set =====")
MSG("inter_ref_pic_set_prediction_flag = " << rps_ptr->inter_ref_pic_set_prediction_flag);
MSG("inter_ref_pic_set_prediction_flag = " << static_cast<uint32_t>(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("delta_rps_sign = " << static_cast<uint32_t>(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_NO_NEWLINE(" " << static_cast<uint32_t>(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_NO_NEWLINE(" " << static_cast<uint32_t>(rps_ptr->use_delta_flag[j]));
}
MSG("");
MSG("num_negative_pics = " << rps_ptr->num_negative_pics);
@@ -2669,7 +2693,7 @@ void HevcVideoParser::PrintStRps(HevcShortTermRps *rps_ptr) {
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_NO_NEWLINE(" " << static_cast<uint32_t>(rps_ptr->used_by_curr_pic_s0_flag[j]));
}
MSG("");
MSG_NO_NEWLINE("delta_poc_s1_minus1[]:");
@@ -2679,7 +2703,7 @@ void HevcVideoParser::PrintStRps(HevcShortTermRps *rps_ptr) {
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_NO_NEWLINE(" " << static_cast<uint32_t>(rps_ptr->used_by_curr_pic_s1_flag[j]));
}
MSG("");
@@ -2695,12 +2719,12 @@ void HevcVideoParser::PrintStRps(HevcShortTermRps *rps_ptr) {
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_NO_NEWLINE(" " << static_cast<uint32_t>(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_NO_NEWLINE(" " << static_cast<uint32_t>(rps_ptr->used_by_curr_pic_s1[j]));
}
MSG("");
}
@@ -2719,4 +2743,71 @@ void HevcVideoParser::PrintLtRefInfo(HevcLongTermRps *lt_info_ptr) {
}
MSG("");
}
void HevcVideoParser::PrintDpb() {
uint32_t i;
MSG("=======================");
MSG("DPB buffer content: ");
MSG("=======================");
MSG("dpb_size = " << dpb_buffer_.dpb_size);
MSG("num_pics_needed_for_output = " << dpb_buffer_.num_pics_needed_for_output);
MSG("dpb_fullness = " << dpb_buffer_.dpb_fullness);
MSG("Frame buffer store:");
for (i = 0; i < HEVC_MAX_DPB_FRAMES; i++) {
HevcPicInfo *p_buf = &dpb_buffer_.frame_buffer_list[i];
MSG("Frame buffer " << i << ": pic_idx = " << p_buf->pic_idx << ", dec_buf_idx = " << p_buf->dec_buf_idx << ", pic_order_cnt = " << p_buf->pic_order_cnt << ", slice_pic_order_cnt_lsb = " << p_buf->slice_pic_order_cnt_lsb << ", decode_order_count = " << p_buf->decode_order_count << ", is_reference = " << p_buf->is_reference << ", use_status = " << p_buf->use_status << ", pic_output_flag = " << p_buf->pic_output_flag);
}
MSG("");
MSG("Decode buffer pool:");
for(i = 0; i < dec_buf_pool_size_; i++) {
DecodeFrameBuffer *p_dec_buf = &decode_buffer_pool_[i];
MSG("Decode buffer " << i << ": use_status = " << p_dec_buf->use_status << ", pic_order_cnt = " << p_dec_buf->pic_order_cnt);
}
MSG("num_output_pics_ = " << num_output_pics_);
if (num_output_pics_) {
MSG("output_pic_list:");
for (i = 0; i < num_output_pics_; i++) {
MSG_NO_NEWLINE(output_pic_list_[i] << ", ");
}
MSG("");
}
}
void HevcVideoParser::PrintVappiBufInfo() {
RocdecHevcPicParams *p_pic_param = &dec_pic_params_.pic_params.hevc;
MSG("=======================");
MSG("VAAPI Buffer Info: ");
MSG("=======================");
MSG("Current buffer:");
MSG_NO_NEWLINE("pic_idx = " << p_pic_param->curr_pic.pic_idx << ", poc = " << p_pic_param->curr_pic.poc);
MSG(", flags = 0x" << std::hex << p_pic_param->curr_pic.flags);
MSG(std::dec);
MSG("Reference pictures:");
for (int i = 0; i < 15; i++) {
RocdecHevcPicture *p_ref_pic = &p_pic_param->ref_frames[i];
MSG_NO_NEWLINE("Ref pic " << i << ": " << "pic_idx = " << p_ref_pic->pic_idx << ", poc = " << p_ref_pic->poc);
MSG(", flags = 0x" << std::hex << p_ref_pic->flags);
MSG_NO_NEWLINE(std::dec);
}
MSG("Slice ref lists:")
for (int slice_index = 0; slice_index < num_slices_; slice_index++) {
RocdecHevcSliceParams *p_slice_param = &slice_param_list_[slice_index];
HevcSliceInfo *p_slice_info = &slice_info_list_[slice_index];
MSG("Slice " << slice_index << " ref list 0:");
for (int i = 0; i <= p_slice_info->slice_header.num_ref_idx_l0_active_minus1; i++) {
MSG("Index " << i << ": " << static_cast<uint32_t>(p_slice_param->ref_pic_list[0][i]));
}
if (p_slice_info->slice_header.slice_type == HEVC_SLICE_TYPE_B) {
MSG("Slice " << slice_index << " ref list 1: ");
for (int i = 0; i <= p_slice_info->slice_header.num_ref_idx_l1_active_minus1; i++) {
MSG("Index " << i << ": " << static_cast<uint32_t>(p_slice_param->ref_pic_list[1][i]));
}
}
MSG("");
}
}
#endif // DBGINFO