From a0dd3fc6b3f209da6331ba2e7efc06ade61468b7 Mon Sep 17 00:00:00 2001 From: jeffqjiangNew <142832361+jeffqjiangNew@users.noreply.github.com> Date: Wed, 9 Apr 2025 20:57:52 -0400 Subject: [PATCH] AVC: Added support for in stream DPB buffer size change. (#553) * * AVC: Added support for in stream DPB buffer size change. * * AVC: Updated change log. --------- Co-authored-by: Kiriti Gowda [ROCm/rocdecode commit: 3d1a1b638eb1153a18955de8aa296ca2bc764126] --- projects/rocdecode/CHANGELOG.md | 2 ++ projects/rocdecode/src/parser/avc_parser.cpp | 20 ++++++++++--------- .../utils/rocvideodecode/roc_video_dec.cpp | 7 ++++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/projects/rocdecode/CHANGELOG.md b/projects/rocdecode/CHANGELOG.md index 1c551f825a..56a392e5d6 100644 --- a/projects/rocdecode/CHANGELOG.md +++ b/projects/rocdecode/CHANGELOG.md @@ -10,6 +10,7 @@ Full documentation for rocDecode is available at [https://rocm.docs.amd.com/proj * CTest for VP9 decode on bitstream reader. * HEVC/AVC stream syntax error handling. * HEVC stream bit depth change handling and DPB buffer size change handling through decoder reconfiguration. +* AVC stream DPB buffer size change handling through decoder reconfiguration. * rocDecode now uses the Cmake CMAKE_PREFIX_PATH directive. ### Optimized @@ -20,6 +21,7 @@ Full documentation for rocDecode is available at [https://rocm.docs.amd.com/proj ### Resolved issues * Fixed a bug in picture files sample "videoDecodePicFiles" that can results in incorrect output frame count. +* Fixed a decoded frame output issue in video size change cases. ### Removed diff --git a/projects/rocdecode/src/parser/avc_parser.cpp b/projects/rocdecode/src/parser/avc_parser.cpp index 5192eec05b..ba1f8998df 100644 --- a/projects/rocdecode/src/parser/avc_parser.cpp +++ b/projects/rocdecode/src/parser/avc_parser.cpp @@ -1237,9 +1237,6 @@ ParserResult AvcVideoParser::ParseSliceHeader(uint8_t *p_stream, size_t stream_s ERR("Empty SPS is referred."); return PARSER_WRONG_STATE; } - // Re-set DPB size. - dpb_buffer_.dpb_size = p_sps->max_num_ref_frames + 1; - dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > AVC_MAX_DPB_FRAMES ? AVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size; new_seq_activated_ = true; // Note: clear this flag after the actions are taken. } p_sps = &sps_list_[active_sps_id_]; @@ -1251,15 +1248,20 @@ ParserResult AvcVideoParser::ParseSliceHeader(uint8_t *p_stream, size_t stream_s pic_width_ = curr_pic_width; pic_height_ = curr_pic_height; // 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. - dpb_buffer_.dpb_size = p_sps->max_num_ref_frames + 1; - dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > AVC_MAX_DPB_FRAMES ? AVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size; new_seq_activated_ = true; // Note: clear this flag after the actions are taken. } - - // Check and adjust decode buffer pool size if needed - if (new_seq_activated_) { + // Check DPB buffer size change + uint32_t dpb_size = p_sps->max_num_ref_frames + 1; + if (dpb_buffer_.dpb_size != dpb_size) { + // Need to flush DPB before changing size + ParserResult ret; + if ((ret = FlushDpb()) != PARSER_OK) { + return ret; + } + dpb_buffer_.dpb_size = dpb_size; + dpb_buffer_.dpb_size = dpb_buffer_.dpb_size > AVC_MAX_DPB_FRAMES ? AVC_MAX_DPB_FRAMES : dpb_buffer_.dpb_size; CheckAndAdjustDecBufPoolSize(dpb_buffer_.dpb_size); + new_seq_activated_ = true; } // Set frame rate if available diff --git a/projects/rocdecode/utils/rocvideodecode/roc_video_dec.cpp b/projects/rocdecode/utils/rocvideodecode/roc_video_dec.cpp index 323e67291a..43e1cacb73 100644 --- a/projects/rocdecode/utils/rocvideodecode/roc_video_dec.cpp +++ b/projects/rocdecode/utils/rocvideodecode/roc_video_dec.cpp @@ -483,13 +483,14 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) { bool is_bit_depth_changed = p_video_format->bit_depth_luma_minus8 != bitdepth_minus_8_; bool is_dec_surface_num_changed = p_video_format->min_num_decode_surfaces != num_decode_surfaces_; + // Flush and clear internal frame store to reconfigure when either coded size or display size has changed. + if (p_reconfig_params_ && p_reconfig_params_->p_fn_reconfigure_flush) + num_frames_flushed_during_reconfig_ += p_reconfig_params_->p_fn_reconfigure_flush(this, p_reconfig_params_->reconfig_flush_mode, static_cast(p_reconfig_params_->p_reconfig_user_struct)); + if (!is_decode_res_changed && !is_display_rect_changed && !is_bit_depth_changed && !is_dec_surface_num_changed && !b_force_recofig_flush_) { return 1; } - // Flush and clear internal frame store to reconfigure when either coded size or display size has changed. - if (p_reconfig_params_ && p_reconfig_params_->p_fn_reconfigure_flush) - num_frames_flushed_during_reconfig_ += p_reconfig_params_->p_fn_reconfigure_flush(this, p_reconfig_params_->reconfig_flush_mode, static_cast(p_reconfig_params_->p_reconfig_user_struct)); // clear the existing output buffers of different size // note that app lose the remaining frames in the vp_frames/vp_frames_q in case application didn't set p_fn_reconfigure_flush_ callback if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) {