From 9c113d5ee90e9f1ec1dc765a08f37ab113d8ee2f Mon Sep 17 00:00:00 2001 From: jeffqjiangNew <142832361+jeffqjiangNew@users.noreply.github.com> Date: Tue, 7 Jan 2025 20:43:49 -0500 Subject: [PATCH] * rocDecode/VP9: Increased DPB buffer size to handle streams with the maximum number of the reference frames allowed. (#488) - DPB buffer size was set to NUM_REF_FRAMES(8) which can not handle streams with 8 reference frames. We increase DPB size from 8 to 10 (same strategy as AV1) to be able to handle these streams. --- src/parser/vp9_defines.h | 27 ++++++++++++++------------- src/parser/vp9_parser.cpp | 12 ++++++------ src/parser/vp9_parser.h | 4 ++-- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/parser/vp9_defines.h b/src/parser/vp9_defines.h index 20102cf58c..9a2e9acb51 100644 --- a/src/parser/vp9_defines.h +++ b/src/parser/vp9_defines.h @@ -24,19 +24,20 @@ THE SOFTWARE. #include -#define VP9_REFS_PER_FRAME 3 // Each inter frame can use up to 3 frames for reference -#define VP9_NUM_REF_FRAMES 8 // Number of frames that can be stored for future reference -#define VP9_MAX_REF_FRAMES 4 // Number of values that can be derived for ref_frame -#define VP9_MAX_SEGMENTS 8 // Number of segments allowed in segmentation map -#define VP9_SEG_LVL_ALT_Q 0 // Index for quantizer segment feature -#define VP9_SEG_LVL_ALT_L 1 // Index for loop filter segment feature -#define VP9_SEG_LVL_REF_FRAME 2 // Index for reference frame segment feature -#define VP9_SEG_LVL_SKIP 3 // Index for skip segment feature -#define VP9_SEG_LVL_MAX 4 // Number of segment features -#define MIN_TILE_WIDTH_B64 4 // Minimum width of a tile in units of superblocks (although tiles on the right hand edge can be narrower) -#define MAX_TILE_WIDTH_B64 64 // Maximum width of a tile in units of superblocks -#define MAX_MODE_LF_DELTAS 2 // Number of different mode types for loop filtering -#define VP9_MAX_LOOP_FILTER 63 // Maximum value used for loop filtering +#define VP9_REFS_PER_FRAME 3 // Each inter frame can use up to 3 frames for reference +#define VP9_NUM_REF_FRAMES 8 // Number of frames that can be stored for future reference +#define VP9_MAX_REF_FRAMES 4 // Number of values that can be derived for ref_frame +#define VP9_MAX_SEGMENTS 8 // Number of segments allowed in segmentation map +#define VP9_SEG_LVL_ALT_Q 0 // Index for quantizer segment feature +#define VP9_SEG_LVL_ALT_L 1 // Index for loop filter segment feature +#define VP9_SEG_LVL_REF_FRAME 2 // Index for reference frame segment feature +#define VP9_SEG_LVL_SKIP 3 // Index for skip segment feature +#define VP9_SEG_LVL_MAX 4 // Number of segment features +#define MIN_TILE_WIDTH_B64 4 // Minimum width of a tile in units of superblocks (although tiles on the right hand edge can be narrower) +#define MAX_TILE_WIDTH_B64 64 // Maximum width of a tile in units of superblocks +#define MAX_MODE_LF_DELTAS 2 // Number of different mode types for loop filtering +#define VP9_MAX_LOOP_FILTER 63 // Maximum value used for loop filtering +#define VP9_BUFFER_POOL_MAX_SIZE 10 // Number of frames in buffer pool typedef enum { kVp9KeyFrame = 0, diff --git a/src/parser/vp9_parser.cpp b/src/parser/vp9_parser.cpp index 2aa7d703f9..442fbd3c3a 100644 --- a/src/parser/vp9_parser.cpp +++ b/src/parser/vp9_parser.cpp @@ -49,7 +49,7 @@ rocDecStatus Vp9VideoParser::Initialize(RocdecParserParams *p_params) { if (parser_params_.max_display_delay < DECODE_BUF_POOL_EXTENSION) { parser_params_.max_display_delay = DECODE_BUF_POOL_EXTENSION; } - CheckAndAdjustDecBufPoolSize(VP9_NUM_REF_FRAMES); + CheckAndAdjustDecBufPoolSize(VP9_BUFFER_POOL_MAX_SIZE); return ROCDEC_SUCCESS; } @@ -352,7 +352,7 @@ void Vp9VideoParser::UpdateRefFrames() { void Vp9VideoParser::InitDpb() { int i; memset(&dpb_buffer_, 0, sizeof(DecodedPictureBuffer)); - for (i = 0; i < VP9_NUM_REF_FRAMES; i++) { + for (i = 0; i < VP9_BUFFER_POOL_MAX_SIZE; i++) { dpb_buffer_.frame_store[i].pic_idx = i; dpb_buffer_.frame_store[i].use_status = kNotUsed; dpb_buffer_.dec_ref_count[i] = 0; @@ -391,12 +391,12 @@ ParserResult Vp9VideoParser::FindFreeInDecBufPool() { ParserResult Vp9VideoParser::FindFreeInDpbAndMark() { int i; - for (i = 0; i < VP9_NUM_REF_FRAMES; i++ ) { + for (i = 0; i < VP9_BUFFER_POOL_MAX_SIZE; i++ ) { if (dpb_buffer_.dec_ref_count[i] == 0) { break; } } - if (i == VP9_NUM_REF_FRAMES) { + if (i == VP9_BUFFER_POOL_MAX_SIZE) { ERR("DPB buffer overflow!"); return PARSER_NOT_FOUND; } @@ -422,7 +422,7 @@ ParserResult Vp9VideoParser::FindFreeInDpbAndMark() { } void Vp9VideoParser::CheckAndUpdateDecStatus() { - for (int i = 0; i < VP9_NUM_REF_FRAMES; i++) { + for (int i = 0; i < VP9_BUFFER_POOL_MAX_SIZE; i++) { if (dpb_buffer_.frame_store[i].use_status != kNotUsed && dpb_buffer_.dec_ref_count[i] == 0) { dpb_buffer_.frame_store[i].use_status = kNotUsed; decode_buffer_pool_[dpb_buffer_.frame_store[i].dec_buf_idx].use_status &= ~kFrameUsedForDecode; @@ -1112,7 +1112,7 @@ void Vp9VideoParser::PrintDpb() { MSG("DPB buffer content: "); MSG("======================="); MSG("Current frame: pic_idx = " << curr_pic_.pic_idx << ", dec_buf_idx = " << curr_pic_.dec_buf_idx); - for (i = 0; i < VP9_NUM_REF_FRAMES; i++) { + for (i = 0; i < VP9_BUFFER_POOL_MAX_SIZE; i++) { MSG("Frame store " << i << ": " << "dec_ref_count = " << dpb_buffer_.dec_ref_count[i] << ", pic_idx = " << dpb_buffer_.frame_store[i].pic_idx << ", dec_buf_idx = " << dpb_buffer_.frame_store[i].dec_buf_idx << ", use_status = " << dpb_buffer_.frame_store[i].use_status); } MSG_NO_NEWLINE("virtual_buffer_index[] ="); diff --git a/src/parser/vp9_parser.h b/src/parser/vp9_parser.h index 5e20e8a84a..3996207e70 100644 --- a/src/parser/vp9_parser.h +++ b/src/parser/vp9_parser.h @@ -63,8 +63,8 @@ protected: /*! \brief Decoded picture buffer */ typedef struct { - Vp9Picture frame_store[VP9_NUM_REF_FRAMES]; // BufferPool - int dec_ref_count[VP9_NUM_REF_FRAMES]; // frame ref count + Vp9Picture frame_store[VP9_BUFFER_POOL_MAX_SIZE]; // BufferPool + int dec_ref_count[VP9_BUFFER_POOL_MAX_SIZE]; // frame ref count // A list of all frame buffers that may be used for reference of the current picture or any // subsequent pictures. The value is the index of a frame in DPB buffer pool. If an entry is // not used as reference, the value should be -1. Borrowed from AV1.