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:
@@ -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
|
||||
Reference in New Issue
Block a user