HEVC: Added DPB size change handling through decoder reconfiguration. (#531)
* * rocDecode/HEVC: Added DPB size change handling through decoder reconfiguration.
* * rocDecode/HEVC: Minor fix.
[ROCm/rocdecode commit: 5988eb16b6]
Este cometimento está contido em:
cometido por
GitHub
ascendente
cd31658919
cometimento
ede21fffa0
@@ -9,7 +9,7 @@ Full documentation for rocDecode is available at [https://rocm.docs.amd.com/proj
|
||||
* VP9 IVF container file parsing support in bitstream reader.
|
||||
* CTest for VP9 decode on bitstream reader.
|
||||
* HEVC stream syntax error handling.
|
||||
* HEVC stream bit depth change handling through decoder reconfiguration.
|
||||
* HEVC stream bit depth change handling and DPB buffer size change handling through decoder reconfiguration.
|
||||
* rocDecode now uses the Cmake CMAKE_PREFIX_PATH directive.
|
||||
|
||||
### Optimized
|
||||
|
||||
@@ -1551,7 +1551,7 @@ 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 = &sps_list_[m_active_sps_id_];
|
||||
new_seq_activated_ = true; // Note: clear this flag after the actions are taken.
|
||||
new_seq_activated_ = true;
|
||||
}
|
||||
|
||||
sps_ptr = &sps_list_[m_active_sps_id_];
|
||||
@@ -1570,7 +1570,7 @@ 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
|
||||
new_seq_activated_ = true; // Note: clear this flag after the actions are taken.
|
||||
new_seq_activated_ = true;
|
||||
}
|
||||
// Check DPB buffer size change
|
||||
uint32_t max_dec_pic_buffering = sps_ptr->sps_max_dec_pic_buffering_minus1[sps_ptr->sps_max_sub_layers_minus1] + 1;
|
||||
@@ -1578,6 +1578,7 @@ ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcS
|
||||
dpb_buffer_.dpb_size = max_dec_pic_buffering;
|
||||
dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > HEVC_MAX_DPB_FRAMES ? HEVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size;
|
||||
CheckAndAdjustDecBufPoolSize(dpb_buffer_.dpb_size);
|
||||
new_seq_activated_ = true;
|
||||
}
|
||||
// Check bit depth change
|
||||
if (bit_depth_luma_minus8_ != sps_ptr->bit_depth_luma_minus8 || bit_depth_chroma_minus8_ != sps_ptr->bit_depth_chroma_minus8) {
|
||||
|
||||
@@ -94,6 +94,7 @@ void RocVideoParser::InitDecBufPool() {
|
||||
|
||||
void RocVideoParser::CheckAndAdjustDecBufPoolSize(int dpb_size) {
|
||||
int min_dec_buf_pool_size = dpb_size + (parser_params_.max_display_delay > DECODE_BUF_POOL_EXTENSION ? parser_params_.max_display_delay : DECODE_BUF_POOL_EXTENSION);
|
||||
// If DPB size decreases, we keep the existing pool and skip reconfiguration.
|
||||
if ( dec_buf_pool_size_ < min_dec_buf_pool_size) {
|
||||
dec_buf_pool_size_ = min_dec_buf_pool_size;
|
||||
decode_buffer_pool_.resize(dec_buf_pool_size_, {0});
|
||||
|
||||
@@ -93,6 +93,9 @@ rocDecStatus RocDecoder::ReconfigureDecoder(RocdecReconfigureDecoderInfo *reconf
|
||||
return rocdec_status;
|
||||
}
|
||||
}
|
||||
if (hip_interop_.size() != reconfig_params->num_decode_surfaces) {
|
||||
hip_interop_.resize(reconfig_params->num_decode_surfaces);
|
||||
}
|
||||
rocdec_status = va_video_decoder_.ReconfigureDecoder(reconfig_params);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Reconfiguration of the decoder failed.");
|
||||
|
||||
@@ -238,7 +238,6 @@ static void GetSurfaceStrideInternal(rocDecVideoSurfaceFormat surface_format, ui
|
||||
* 0: fail, 1: succeeded, > 1: override dpb size of parser (set by RocdecParserParams::max_num_decode_surfaces while creating parser)
|
||||
*/
|
||||
int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
||||
|
||||
if (p_video_format == nullptr) {
|
||||
ROCDEC_THROW("Rocdec:: Invalid video format in HandleVideoSequence: ", ROCDEC_INVALID_PARAMETER);
|
||||
return 0;
|
||||
@@ -260,8 +259,6 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
||||
;
|
||||
input_video_info_str_ << std::endl;
|
||||
|
||||
int num_decode_surfaces = p_video_format->min_num_decode_surfaces;
|
||||
|
||||
RocdecDecodeCaps decode_caps;
|
||||
memset(&decode_caps, 0, sizeof(decode_caps));
|
||||
decode_caps.codec_type = p_video_format->codec;
|
||||
@@ -329,6 +326,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
||||
disp_rect_.right = p_video_format->display_area.right;
|
||||
disp_width_ = p_video_format->display_area.right - p_video_format->display_area.left;
|
||||
disp_height_ = p_video_format->display_area.bottom - p_video_format->display_area.top;
|
||||
num_decode_surfaces_ = p_video_format->min_num_decode_surfaces;
|
||||
|
||||
// AV1 has max width/height of sequence in sequence header
|
||||
if (codec_id_ == rocDecVideoCodec_AV1 && p_video_format->seqhdr_data_length > 0) {
|
||||
@@ -350,7 +348,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
||||
videoDecodeCreateInfo.chroma_format = video_chroma_format_;
|
||||
videoDecodeCreateInfo.output_format = video_surface_format_;
|
||||
videoDecodeCreateInfo.bit_depth_minus_8 = bitdepth_minus_8_;
|
||||
videoDecodeCreateInfo.num_decode_surfaces = num_decode_surfaces;
|
||||
videoDecodeCreateInfo.num_decode_surfaces = num_decode_surfaces_;
|
||||
videoDecodeCreateInfo.width = coded_width_;
|
||||
videoDecodeCreateInfo.height = coded_height_;
|
||||
videoDecodeCreateInfo.max_width = max_width_;
|
||||
@@ -419,7 +417,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
||||
ROCDEC_API_CALL(rocDecCreateDecoder(&roc_decoder_, &videoDecodeCreateInfo));
|
||||
double elapsed_time = StopTimer(start_time);
|
||||
AddDecoderSessionOverHead(std::this_thread::get_id(), elapsed_time);
|
||||
return num_decode_surfaces;
|
||||
return num_decode_surfaces_;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,13 +474,16 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
||||
ROCDEC_THROW("Reconfigure Not supported for chroma format change", ROCDEC_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_decode_res_changed = !(p_video_format->coded_width == coded_width_ && p_video_format->coded_height == coded_height_);
|
||||
bool is_display_rect_changed = !(p_video_format->display_area.bottom == disp_rect_.bottom &&
|
||||
p_video_format->display_area.top == disp_rect_.top &&
|
||||
p_video_format->display_area.left == disp_rect_.left &&
|
||||
p_video_format->display_area.right == disp_rect_.right);
|
||||
bool is_bit_depth_changed = p_video_format->bit_depth_luma_minus8 != bitdepth_minus_8_;
|
||||
if (!is_decode_res_changed && !is_display_rect_changed && !is_bit_depth_changed && !b_force_recofig_flush_) {
|
||||
bool is_dec_surface_num_changed = p_video_format->min_num_decode_surfaces != num_decode_surfaces_;
|
||||
|
||||
if (!is_decode_res_changed && !is_display_rect_changed && !is_bit_depth_changed && !is_dec_surface_num_changed && !b_force_recofig_flush_) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -542,6 +543,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
||||
else if (video_chroma_format_ == rocDecVideoChromaFormat_422)
|
||||
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV422_16Bit : rocDecVideoSurfaceFormat_YUV422;
|
||||
}
|
||||
num_decode_surfaces_ = p_video_format->min_num_decode_surfaces;
|
||||
|
||||
if (p_video_format->reconfig_options == ROCDEC_RECONFIG_NEW_SURFACES) {
|
||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL || out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED) {
|
||||
@@ -583,7 +585,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
||||
|
||||
// If the coded_width or coded_height hasn't changed but display resolution has changed, then need to update width and height for
|
||||
// correct output with cropping. There is no need to reconfigure the decoder.
|
||||
if (!is_decode_res_changed && is_display_rect_changed && !is_bit_depth_changed) {
|
||||
if (!is_decode_res_changed && is_display_rect_changed && !is_bit_depth_changed && !is_dec_surface_num_changed) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -621,6 +623,9 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
||||
}
|
||||
if (is_bit_depth_changed) {
|
||||
input_video_info_str_ << "Input Video Bit Depth Changed:" << std::endl;
|
||||
}
|
||||
if (is_dec_surface_num_changed) {
|
||||
input_video_info_str_ << "Number of decoded surfaces Changed:" << std::endl;
|
||||
}
|
||||
input_video_info_str_ << "\tCoded size : [" << p_video_format->coded_width << ", " << p_video_format->coded_height << "]" << std::endl
|
||||
<< "\tDisplay area : [" << p_video_format->display_area.left << ", " << p_video_format->display_area.top << ", "
|
||||
@@ -634,7 +639,9 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
||||
input_video_info_str_ << std::endl;
|
||||
std::cout << input_video_info_str_.str();
|
||||
|
||||
is_decoder_reconfigured_ = true;
|
||||
if (is_decode_res_changed || is_bit_depth_changed) {
|
||||
is_decoder_reconfigured_ = true;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -505,6 +505,7 @@ class RocVideoDecoder {
|
||||
uint32_t target_height_ = 0;
|
||||
int max_width_ = 0, max_height_ = 0;
|
||||
uint32_t chroma_height_ = 0, chroma_width_ = 0;
|
||||
uint32_t num_decode_surfaces_ = 0;
|
||||
uint32_t num_chroma_planes_ = 0;
|
||||
uint32_t num_components_ = 0;
|
||||
uint32_t surface_stride_ = 0;
|
||||
|
||||
Criar uma nova questão referindo esta
Bloquear um utilizador