HEVC: Added bit depth change support in decoder reconfiguration. (#527)

* * rocDecode/HEVC: Added bit depth change support in decoder reconfiguration.

* * rocDecode/HEVC: Removed a comment line.

* * rocDecode/HEVC: Updated change log.

* * rocDecode/HEVC: Used the reserved space in RocdecReconfigureDecoderInfo structure for bit_depth_minus_8 field to be backward compatible. Added bit depth to the new sequence file name when we dump output in decoder reconfiguration case.

* * rocDecode/HEVC: Added bit depth change support in decoder reconfiguration.

* * rocDecode/HEVC: Removed a comment line.

* * rocDecode/HEVC: Updated change log.

* * rocDecode/HEVC: Used the reserved space in RocdecReconfigureDecoderInfo structure for bit_depth_minus_8 field to be backward compatible. Added bit depth to the new sequence file name when we dump output in decoder reconfiguration case.

* * rocDecode/HEVC: Changes based on review comments.

* * rocDecode: Fixed a bug related to 422 surface format assignment.

* * rocDecode: Fixed build warnings with some sample apps.
Bu işleme şunda yer alıyor:
jeffqjiangNew
2025-03-13 09:29:25 -04:00
işlemeyi yapan: GitHub
ebeveyn ac74540c19
işleme ab7546930f
11 değiştirilmiş dosya ile 76 ekleme ve 23 silme
+2 -1
Dosyayı Görüntüle
@@ -2,13 +2,14 @@
Full documentation for rocDecode is available at [https://rocm.docs.amd.com/projects/rocDecode/en/latest/](https://rocm.docs.amd.com/projects/rocDecode/en/latest/)
## (Unreleased) rocDecode 0.11.0
## (Unreleased) rocDecode 0.11.1
### Added
* 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.
### Changed
+1 -1
Dosyayı Görüntüle
@@ -39,7 +39,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED On)
# NOTE: Match version with api/rocdecode_version.h
set(VERSION "0.11.0")
set(VERSION "0.11.1")
# Set Project Version and Language
project(rocdecode VERSION ${VERSION} LANGUAGES CXX)
+6 -2
Dosyayı Görüntüle
@@ -108,7 +108,10 @@ typedef enum rocDecVideoSurfaceFormat_enum {
rocDecVideoSurfaceFormat_YUV444_16Bit = 3, /**< 16 bit Planar YUV [Y plane followed by U and V planes].
Can be used for 10 bit(6LSB bits 0), 12 bit (4LSB bits 0) */
rocDecVideoSurfaceFormat_YUV420 = 4, /**< Planar YUV [Y plane followed by U and V planes in 4:2:0 format] */
rocDecVideoSurfaceFormat_YUV420_16Bit = 5, /**< 16 bit Planar YUV [Y plane followed by U and V planes in ].
rocDecVideoSurfaceFormat_YUV420_16Bit = 5, /**< 16 bit Planar YUV [Y plane followed by U and V planes in 4:2:0 format].
Can be used for 10 bit(LSB), 12 bit (LSB) */
rocDecVideoSurfaceFormat_YUV422 = 6, /**< Planar YUV [Y plane followed by U and V planes in 4:2:2 format] */
rocDecVideoSurfaceFormat_YUV422_16Bit = 7, /**< 16 bit Planar YUV [Y plane followed by U and V planes in 4:2:2 format].
Can be used for 10 bit(LSB), 12 bit (LSB) */
} rocDecVideoSurfaceFormat;
@@ -227,7 +230,8 @@ typedef struct _RocdecReconfigureDecoderInfo {
uint32_t target_width; /**< IN: Post processed output width */
uint32_t target_height; /**< IN: Post Processed output height */
uint32_t num_decode_surfaces; /**< IN: Maximum number of internal decode surfaces */
uint32_t reserved_1[12]; /**< Reserved for future use. Set to Zero */
uint32_t bit_depth_minus_8; /**< IN: The Value "BitDepth minus 8" */
uint32_t reserved_1[11]; /**< Reserved for future use. Set to Zero */
struct {
int16_t left;
int16_t top;
+1 -1
Dosyayı Görüntüle
@@ -36,7 +36,7 @@ extern "C" {
/* NOTE: Match version with CMakeLists.txt */
#define ROCDECODE_MAJOR_VERSION 0
#define ROCDECODE_MINOR_VERSION 11
#define ROCDECODE_MICRO_VERSION 0
#define ROCDECODE_MICRO_VERSION 1
/**
+7 -1
Dosyayı Görüntüle
@@ -1566,7 +1566,7 @@ ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcS
}
// Check video dimension change
if ( pic_width_ != sps_ptr->pic_width_in_luma_samples || pic_height_ != sps_ptr->pic_height_in_luma_samples) {
if (pic_width_ != sps_ptr->pic_width_in_luma_samples || pic_height_ != sps_ptr->pic_height_in_luma_samples) {
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
@@ -1579,6 +1579,12 @@ ParserResult HevcVideoParser::ParseSliceHeader(uint8_t *nalu, size_t size, HevcS
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);
}
// 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) {
bit_depth_luma_minus8_ = sps_ptr->bit_depth_luma_minus8;
bit_depth_chroma_minus8_ = sps_ptr->bit_depth_chroma_minus8;
new_seq_activated_ = true;
}
// Set frame rate if available
if (new_seq_activated_) {
+2
Dosyayı Görüntüle
@@ -26,6 +26,8 @@ RocVideoParser::RocVideoParser() {
pic_count_ = 0;
pic_width_ = 0;
pic_height_ = 0;
bit_depth_luma_minus8_ = 0;
bit_depth_chroma_minus8_ = 0;
new_seq_activated_ = false;
frame_rate_.numerator = 0;
frame_rate_.denominator = 0;
+2
Dosyayı Görüntüle
@@ -138,6 +138,8 @@ protected:
uint32_t pic_count_; // decoded picture count for the current bitstream
uint32_t pic_width_;
uint32_t pic_height_;
uint32_t bit_depth_luma_minus8_;
uint32_t bit_depth_chroma_minus8_;
bool new_seq_activated_;
// Decoded buffer pool
+15 -1
Dosyayı Görüntüle
@@ -340,6 +340,11 @@ rocDecStatus VaapiVideoDecoder::ReconfigureDecoder(RocdecReconfigureDecoderInfo
}
CHECK_VAAPI(vaDestroySurfaces(va_display_, va_surface_ids_.data(), va_surface_ids_.size()));
CHECK_VAAPI(vaDestroyContext(va_display_, va_context_id_));
// Need to re-create VA config if bit deepth changes
bool create_va_config = decoder_create_info_.bit_depth_minus_8 != reconfig_params->bit_depth_minus_8 ? true : false;
if (create_va_config) {
CHECK_VAAPI(vaDestroyConfig(va_display_, va_config_id_));
}
va_surface_ids_.clear();
decoder_create_info_.width = reconfig_params->width;
@@ -347,8 +352,17 @@ rocDecStatus VaapiVideoDecoder::ReconfigureDecoder(RocdecReconfigureDecoderInfo
decoder_create_info_.num_decode_surfaces = reconfig_params->num_decode_surfaces;
decoder_create_info_.target_height = reconfig_params->target_height;
decoder_create_info_.target_width = reconfig_params->target_width;
decoder_create_info_.bit_depth_minus_8 = reconfig_params->bit_depth_minus_8;
rocDecStatus rocdec_status = CreateSurfaces();
rocDecStatus rocdec_status;
if (create_va_config) {
rocdec_status = CreateDecoderConfig();
if (rocdec_status != ROCDEC_SUCCESS) {
ERR("Failed to create a VAAPI decoder configuration.");
return rocdec_status;
}
}
rocdec_status = CreateSurfaces();
if (rocdec_status != ROCDEC_SUCCESS) {
ERR("Failed to create VAAPI surfaces during the decoder reconfiguration.");
return rocdec_status;
+2 -2
Dosyayı Görüntüle
@@ -49,14 +49,14 @@ static inline float GetChromaWidthFactor(rocDecVideoSurfaceFormat surface_format
switch (surface_format) {
case rocDecVideoSurfaceFormat_NV12:
case rocDecVideoSurfaceFormat_P016:
factor = 1.0;
break;
case rocDecVideoSurfaceFormat_YUV444:
case rocDecVideoSurfaceFormat_YUV444_16Bit:
factor = 1.0;
break;
case rocDecVideoSurfaceFormat_YUV420:
case rocDecVideoSurfaceFormat_YUV420_16Bit:
case rocDecVideoSurfaceFormat_YUV422:
case rocDecVideoSurfaceFormat_YUV422_16Bit:
factor = 0.5;
break;
}
+34 -12
Dosyayı Görüntüle
@@ -222,7 +222,14 @@ static void GetSurfaceStrideInternal(rocDecVideoSurfaceFormat surface_format, ui
*pitch = align(width, 128) * 2;
*vstride = align(height, 16);
break;
case rocDecVideoSurfaceFormat_YUV422:
*pitch = align(width, 256);
*vstride = align(height, 16);
break;
case rocDecVideoSurfaceFormat_YUV422_16Bit:
*pitch = align(width, 128) * 2;
*vstride = align(height, 16);
break;
}
return;
}
@@ -298,7 +305,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
else if (video_chroma_format_ == rocDecVideoChromaFormat_444)
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV444_16Bit : rocDecVideoSurfaceFormat_YUV444;
else if (video_chroma_format_ == rocDecVideoChromaFormat_422)
video_surface_format_ = rocDecVideoSurfaceFormat_NV12;
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV422_16Bit : rocDecVideoSurfaceFormat_YUV422;
// Check if output format supported. If not, check falback options
if (!(decode_caps.output_format_mask & (1 << video_surface_format_))){
@@ -469,17 +476,13 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
ROCDEC_THROW("Reconfigure Not supported for chroma format change", ROCDEC_NOT_SUPPORTED);
return 0;
}
if (p_video_format->bit_depth_luma_minus8 != bitdepth_minus_8_){
ROCDEC_THROW("Reconfigure Not supported for bit depth 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);
if (!is_decode_res_changed && !is_display_rect_changed && !b_force_recofig_flush_) {
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_) {
return 1;
}
@@ -527,6 +530,18 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
target_height_ = (crop_rect_.bottom - crop_rect_.top + 1) & ~1;
}
}
if (is_bit_depth_changed) {
bitdepth_minus_8_ = p_video_format->bit_depth_luma_minus8;
byte_per_pixel_ = bitdepth_minus_8_ > 0 ? 2 : 1;
// Set the output surface format same as chroma format
if (video_chroma_format_ == rocDecVideoChromaFormat_420 || video_chroma_format_ == rocDecVideoChromaFormat_Monochrome)
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_P016 : rocDecVideoSurfaceFormat_NV12;
else if (video_chroma_format_ == rocDecVideoChromaFormat_444)
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV444_16Bit : rocDecVideoSurfaceFormat_YUV444;
else if (video_chroma_format_ == rocDecVideoChromaFormat_422)
video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV422_16Bit : rocDecVideoSurfaceFormat_YUV422;
}
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) {
@@ -568,7 +583,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) {
if (!is_decode_res_changed && is_display_rect_changed && !is_bit_depth_changed) {
return 1;
}
@@ -577,6 +592,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
reconfig_params.height = coded_height_;
reconfig_params.target_width = target_width_;
reconfig_params.target_height = target_height_;
reconfig_params.bit_depth_minus_8 = bitdepth_minus_8_;
reconfig_params.num_decode_surfaces = p_video_format->min_num_decode_surfaces;
if (!(crop_rect_.right && crop_rect_.bottom)) {
reconfig_params.display_rect.top = disp_rect_.top;
@@ -600,10 +616,16 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
input_video_info_str_.str("");
input_video_info_str_.clear();
input_video_info_str_ << "Input Video Resolution Changed:" << std::endl
<< "\tCoded size : [" << p_video_format->coded_width << ", " << p_video_format->coded_height << "]" << std::endl
if (is_decode_res_changed) {
input_video_info_str_ << "Input Video Resolution Changed:" << std::endl;
}
if (is_bit_depth_changed) {
input_video_info_str_ << "Input Video Bit Depth 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 << ", "
<< p_video_format->display_area.right << ", " << p_video_format->display_area.bottom << "]" << std::endl;
input_video_info_str_ << "\tBit depth : " << reconfig_params.bit_depth_minus_8 + 8 << std::endl;
input_video_info_str_ << std::endl;
input_video_info_str_ << "Video Decoding Params:" << std::endl
<< "\tNum Surfaces : " << reconfig_params.num_decode_surfaces << std::endl
@@ -947,7 +969,7 @@ void RocVideoDecoder::SaveFrameToFile(std::string output_file_name, void *surf_m
if (!current_output_filename.compare(output_file_name)) {
std::string::size_type const pos(output_file_name.find_last_of('.'));
extra_output_file_count_++;
std::string to_append = "_" + std::to_string(surf_info->output_width) + "_" + std::to_string(surf_info->output_height) + "_" + std::to_string(extra_output_file_count_);
std::string to_append = "_" + std::to_string(surf_info->output_width) + "_" + std::to_string(surf_info->output_height) + "_" + std::to_string(surf_info->bit_depth) + "bit" + "_" + std::to_string(extra_output_file_count_);
if (pos != std::string::npos) {
output_file_name.insert(pos, to_append);
} else {
+4 -2
Dosyayı Görüntüle
@@ -83,10 +83,10 @@ inline int GetChromaPlaneCount(rocDecVideoSurfaceFormat surface_format) {
break;
case rocDecVideoSurfaceFormat_YUV444:
case rocDecVideoSurfaceFormat_YUV444_16Bit:
num_planes = 2;
break;
case rocDecVideoSurfaceFormat_YUV420:
case rocDecVideoSurfaceFormat_YUV420_16Bit:
case rocDecVideoSurfaceFormat_YUV422:
case rocDecVideoSurfaceFormat_YUV422_16Bit:
num_planes = 2;
break;
}
@@ -103,6 +103,8 @@ inline float GetChromaHeightFactor(rocDecVideoSurfaceFormat surface_format) {
case rocDecVideoSurfaceFormat_YUV420_16Bit:
factor = 0.5;
break;
case rocDecVideoSurfaceFormat_YUV422:
case rocDecVideoSurfaceFormat_YUV422_16Bit:
case rocDecVideoSurfaceFormat_YUV444:
case rocDecVideoSurfaceFormat_YUV444_16Bit:
factor = 1.0;