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:
işlemeyi yapan:
GitHub
ebeveyn
ac74540c19
işleme
ab7546930f
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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_) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Yeni konuda referans
Bir kullanıcı engelle