From a13ce87a9b74f5938ac6bfd6ccbdd4de8dfc3c77 Mon Sep 17 00:00:00 2001
From: jeffqjiangNew <142832361+jeffqjiangNew@users.noreply.github.com>
Date: Thu, 27 Jun 2024 10:26:21 -0400
Subject: [PATCH] * rocDecode/AV1: Basic inter decode is up and running. (#376)
- Added initial support for DPB and decode/display buffer management.
- Added initial display support.
- Added reference frame set up.
- Fixed an issue with cdef_y_sec_strength/cdef_uv_sec_strength parsing. We should leave the conditional increment to VA-API driver or below due to VA-API formatting.
[ROCm/rocdecode commit: 54419dcca3b27708bed8ccd866559dfc2f426a63]
---
projects/rocdecode/src/parser/av1_defines.h | 2 +-
projects/rocdecode/src/parser/av1_parser.cpp | 209 +++++++++++++------
projects/rocdecode/src/parser/av1_parser.h | 58 +++--
3 files changed, 184 insertions(+), 85 deletions(-)
diff --git a/projects/rocdecode/src/parser/av1_defines.h b/projects/rocdecode/src/parser/av1_defines.h
index a0f77624e0..00e0e251dd 100644
--- a/projects/rocdecode/src/parser/av1_defines.h
+++ b/projects/rocdecode/src/parser/av1_defines.h
@@ -42,9 +42,9 @@ THE SOFTWARE.
#define NUM_REF_FRAMES 8
#define PRIMARY_REF_NONE 7
-
#define REFS_PER_FRAME 7 // Number of reference frames that can be used for inter prediction
#define TOTAL_REFS_PER_FRAME 8 // Number of reference frame types (including intra type)
+#define BUFFER_POOL_MAX_SIZE 10 // Number of frames in buffer pool
#define MAX_TILE_WIDTH 4096 // Maximum width of a tile in units of luma samples
#define MAX_TILE_AREA 4096 * 2304 // Maximum area of a tile in units of luma samples
diff --git a/projects/rocdecode/src/parser/av1_parser.cpp b/projects/rocdecode/src/parser/av1_parser.cpp
index 113775a42b..8570c0a111 100644
--- a/projects/rocdecode/src/parser/av1_parser.cpp
+++ b/projects/rocdecode/src/parser/av1_parser.cpp
@@ -27,14 +27,21 @@ Av1VideoParser::Av1VideoParser() {
seen_frame_header_ = 0;
tile_param_list_.assign(INIT_SLICE_LIST_NUM, {0});
memset(&curr_pic_, 0, sizeof(Av1Picture));
+ memset(&dpb_buffer_, 0, sizeof(DecodedPictureBuffer));
memset(&tile_group_data_, 0, sizeof(Av1TileGroupDataInfo));
+ InitDpb();
}
Av1VideoParser::~Av1VideoParser() {
}
rocDecStatus Av1VideoParser::Initialize(RocdecParserParams *p_params) {
- return RocVideoParser::Initialize(p_params);
+ rocDecStatus ret;
+ if ((ret = RocVideoParser::Initialize(p_params)) != ROCDEC_SUCCESS) {
+ return ret;
+ }
+ CheckAndAdjustDecBufPoolSize(BUFFER_POOL_MAX_SIZE);
+ return ROCDEC_SUCCESS;
}
rocDecStatus Av1VideoParser::UnInitialize() {
@@ -51,6 +58,11 @@ rocDecStatus Av1VideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
// If no payload and EOS is not set, treated as invalid.
return ROCDEC_INVALID_PARAMETER;
}
+ if (p_data->flags & ROCDEC_PKT_ENDOFSTREAM) {
+ if (FlushDpb() != PARSER_OK) {
+ return ROCDEC_RUNTIME_ERROR;
+ }
+ }
return ROCDEC_SUCCESS;
}
@@ -117,24 +129,36 @@ ParserResult Av1VideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t
// Init Roc decoder for the first time or reconfigure the existing decoder
if (new_seq_activated_) {
- if (NotifyNewSequence(&seq_header_, &frame_header_) != PARSER_OK) {
- return PARSER_FAIL;
+ if ((ret = NotifyNewSequence(&seq_header_, &frame_header_)) != PARSER_OK) {
+ return ret;
}
new_seq_activated_ = false;
}
// Submit decode when we have the entire frame data
if (tile_group_data_.tile_number && tile_group_data_.tg_end == tile_group_data_.num_tiles - 1) {
- // Temp code for intra testing
- /* if (FindFreeInDecBufPool() != PARSER_OK) {
- return PARSER_FAIL;
- }*/
- if (SendPicForDecode() != PARSER_OK) {
+ if ((ret = FindFreeInDecBufPool()) != PARSER_OK) {
+ return ret;
+ }
+ if ((ret = FindFreeInDpbAndMark()) != PARSER_OK) {
+ return ret;
+ }
+ if ((ret = SendPicForDecode()) != PARSER_OK) {
ERR(STR("Failed to decode!"));
- return PARSER_FAIL;
+ return ret;
}
+ UpdateRefFrames();
+
+ dpb_buffer_.dec_ref_count[curr_pic_.pic_idx]--;
memset(&tile_group_data_, 0, sizeof(Av1TileGroupDataInfo));
+
+ // Output decoded pictures from DPB if any are ready
+ if (pfn_display_picture_cb_ && num_output_pics_ > 0) {
+ if ((ret = OutputDecodedPictures(false)) != PARSER_OK) {
+ return ret;
+ }
+ }
pic_count_++;
}
};
@@ -241,14 +265,18 @@ ParserResult Av1VideoParser::SendPicForDecode() {
p_pic_param->frame_width_minus1 = p_frame_header->frame_size.frame_width_minus_1;
p_pic_param->frame_height_minus1 = p_frame_header->frame_size.frame_height_minus_1;
- p_pic_param->output_frame_width_in_tiles_minus_1 = 0; // Todo for tile list OBU
- p_pic_param->output_frame_height_in_tiles_minus_1 = 0; // Todo for tile list OBU
+ p_pic_param->output_frame_width_in_tiles_minus_1 = 0; // Todo for large scale tile
+ p_pic_param->output_frame_height_in_tiles_minus_1 = 0; // Todo for large scale tile
- for (i = 0; i < NUM_REF_FRAMES; i++) { // Todo for inter frames
- p_pic_param->ref_frame_map[i] = 0xFF;
+ for (i = 0; i < NUM_REF_FRAMES; i++) {
+ if (dpb_buffer_.virtual_buffer_index[i] != -1) {
+ p_pic_param->ref_frame_map[i] = dpb_buffer_.frame_store[dpb_buffer_.virtual_buffer_index[i]].dec_buf_idx;
+ } else {
+ p_pic_param->ref_frame_map[i] = 0xFF;
+ }
}
- for (i = 0; i < REFS_PER_FRAME; i++) { // Todo for inter frames
- p_pic_param->ref_frame_idx[i] = 0xFF;
+ for (i = 0; i < REFS_PER_FRAME; i++) {
+ p_pic_param->ref_frame_idx[i] = frame_header_.ref_frame_idx[i];
}
p_pic_param->primary_ref_frame = p_frame_header->primary_ref_frame;
p_pic_param->order_hint = p_frame_header->order_hint;
@@ -310,7 +338,7 @@ ParserResult Av1VideoParser::SendPicForDecode() {
for (i = 0; i < p_pic_param->tile_rows; i++) {
p_pic_param->height_in_sbs_minus_1[i] = p_frame_header->tile_info.height_in_sbs_minus_1[i];
}
- p_pic_param->tile_count_minus_1 = 0; // Todo for tile list OBU
+ p_pic_param->tile_count_minus_1 = 0; // Todo for large scale tile
p_pic_param->context_update_tile_id = p_frame_header->tile_info.context_update_tile_id;
p_pic_param->pic_info_fields.bits.frame_type = p_frame_header->frame_type;
@@ -328,7 +356,7 @@ ParserResult Av1VideoParser::SendPicForDecode() {
p_pic_param->pic_info_fields.bits.disable_frame_end_update_cdf = p_frame_header->disable_frame_end_update_cdf;
p_pic_param->pic_info_fields.bits.uniform_tile_spacing_flag = p_frame_header->tile_info.uniform_tile_spacing_flag;
p_pic_param->pic_info_fields.bits.allow_warped_motion = p_frame_header->allow_warped_motion;
- p_pic_param->pic_info_fields.bits.large_scale_tile = 0; // Todo for tile list OBU
+ p_pic_param->pic_info_fields.bits.large_scale_tile = 0;
p_pic_param->superres_scale_denominator = p_frame_header->frame_size.superres_params.super_res_denom;
p_pic_param->interp_filter = p_frame_header->interpolation_filter;
@@ -402,8 +430,8 @@ ParserResult Av1VideoParser::SendPicForDecode() {
p_tile_param->tile_column = p_tile_info->tile_col;
p_tile_param->tg_start = tile_group_data_.tg_start;
p_tile_param->tg_end = tile_group_data_.tg_end;
- p_tile_param->anchor_frame_idx = 0; // // Todo for tile list OBU
- p_tile_param->tile_idx_in_tile_list = 0; // // Todo for tile list OBU
+ p_tile_param->anchor_frame_idx = 0; // Todo for large scale tile
+ p_tile_param->tile_idx_in_tile_list = 0; // Todo large scale tile
}
dec_pic_params_.slice_params.av1 = tile_param_list_.data();
@@ -419,6 +447,41 @@ ParserResult Av1VideoParser::SendPicForDecode() {
}
}
+void Av1VideoParser::UpdateRefFrames() {
+ for (int i = 0; i < NUM_REF_FRAMES; i++) {
+ if ((frame_header_.refresh_frame_flags >> i) & 1) {
+ dpb_buffer_.ref_valid[i] = 1;
+ dpb_buffer_.ref_frame_id[i] = curr_pic_.current_frame_id;
+ dpb_buffer_.ref_frame_type[i] = curr_pic_.frame_type;
+ dpb_buffer_.ref_order_hint[i] = curr_pic_.order_hint;
+ if (dpb_buffer_.virtual_buffer_index[i] != -1) {
+ dpb_buffer_.dec_ref_count[dpb_buffer_.virtual_buffer_index[i]]--;
+ }
+ dpb_buffer_.virtual_buffer_index[i] = curr_pic_.pic_idx;
+ dpb_buffer_.dec_ref_count[curr_pic_.pic_idx]++;
+ }
+ }
+}
+
+void Av1VideoParser::InitDpb() {
+ int i;
+ for (i = 0; i < BUFFER_POOL_MAX_SIZE; i++) {
+ dpb_buffer_.dec_ref_count[i] = 0;
+ }
+ for (i = 0; i < NUM_REF_FRAMES; i++) {
+ dpb_buffer_.virtual_buffer_index[i] = -1;
+ }
+}
+
+ParserResult Av1VideoParser::FlushDpb() {
+ if (pfn_display_picture_cb_ && num_output_pics_ > 0) {
+ if (OutputDecodedPictures(true) != PARSER_OK) {
+ return PARSER_FAIL;
+ }
+ }
+ return PARSER_OK;
+}
+
ParserResult Av1VideoParser::FindFreeInDecBufPool() {
int dec_buf_index;
// Find a free buffer in decode buffer pool
@@ -435,6 +498,39 @@ ParserResult Av1VideoParser::FindFreeInDecBufPool() {
return PARSER_OK;
}
+ParserResult Av1VideoParser::FindFreeInDpbAndMark() {
+ int i;
+ for (i = 0; i < BUFFER_POOL_MAX_SIZE; i++ ) {
+ if (dpb_buffer_.dec_ref_count[i] == 0) {
+ break;
+ }
+ }
+ if (i == BUFFER_POOL_MAX_SIZE) {
+ ERR("DPB buffer overflow!");
+ return PARSER_NOT_FOUND;
+ }
+
+ curr_pic_.pic_idx = i;
+ curr_pic_.use_status = kFrameUsedForDecode;
+ dpb_buffer_.frame_store[curr_pic_.pic_idx] = curr_pic_;
+ dpb_buffer_.dec_ref_count[curr_pic_.pic_idx]++;
+ // Mark as used in decode/display buffer pool
+ decode_buffer_pool_[curr_pic_.dec_buf_idx].use_status |= kFrameUsedForDecode;
+ if (pfn_display_picture_cb_ && curr_pic_.show_frame) {
+ decode_buffer_pool_[curr_pic_.dec_buf_idx].use_status |= kFrameUsedForDisplay;
+ // Insert into output/display picture list
+ if (num_output_pics_ >= dec_buf_pool_size_) {
+ ERR("Display list size larger than decode buffer pool size!");
+ return PARSER_OUT_OF_RANGE;
+ } else {
+ output_pic_list_[num_output_pics_] = curr_pic_.dec_buf_idx;
+ num_output_pics_++;
+ }
+ }
+
+ return PARSER_OK;
+}
+
ParserResult Av1VideoParser::ParseObuHeader(const uint8_t *p_stream) {
size_t offset = 0;
obu_header_.size = 1;
@@ -650,6 +746,10 @@ ParserResult Av1VideoParser::ParseFrameHeaderObu(uint8_t *p_stream, size_t size,
seen_frame_header_ = 1;
}
}
+ curr_pic_.show_frame = frame_header_.show_frame;
+ curr_pic_.current_frame_id = frame_header_.current_frame_id;
+ curr_pic_.order_hint = frame_header_.order_hint;
+ curr_pic_.frame_type = frame_header_.frame_type;
return PARSER_OK;
}
@@ -684,7 +784,7 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
if (p_seq_header->frame_id_numbers_present_flag) {
p_frame_header->display_frame_id = Parser::ReadBits(p_stream, offset, frame_id_len);
}
- p_frame_header->frame_type = ref_frame_type_[p_frame_header->frame_to_show_map_idx];
+ p_frame_header->frame_type = dpb_buffer_.ref_frame_type[p_frame_header->frame_to_show_map_idx];
if (p_frame_header->frame_type == kKeyFrame) {
p_frame_header->refresh_frame_flags = all_frames;
}
@@ -719,8 +819,8 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
if (p_frame_header->frame_type == kKeyFrame && p_frame_header->show_frame) {
for (i = 0; i < NUM_REF_FRAMES; i++) {
- ref_valid_[i] = 0;
- ref_order_hint_[i] = 0;
+ dpb_buffer_.ref_valid[i] = 0;
+ dpb_buffer_.ref_order_hint[i] = 0;
}
for (i = 0; i < REFS_PER_FRAME; i++) {
p_frame_header->order_hints[kLastFrame + i] = 0;
@@ -795,18 +895,12 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
} else {
p_frame_header->refresh_frame_flags = Parser::ReadBits(p_stream, offset, 8);
}
- // Clear reference list for kKeyFrame
- if (p_frame_header->frame_type == kKeyFrame) {
- for (i = 0; i < REFS_PER_FRAME; i++) {
- ref_pictures_[i].pic_idx = INVALID_INDEX;
- }
- }
if (!p_frame_header->frame_is_intra || p_frame_header->refresh_frame_flags != all_frames) {
if (p_frame_header->error_resilient_mode && p_seq_header->enable_order_hint) {
for (i = 0; i < NUM_REF_FRAMES; i++) {
p_frame_header->ref_order_hint[i] = Parser::ReadBits(p_stream, offset, p_seq_header->order_hint_bits);
- if (p_frame_header->ref_order_hint[i] != ref_order_hint_[i]) {
- ref_valid_[i] = 0;
+ if (p_frame_header->ref_order_hint[i] != dpb_buffer_.ref_order_hint[i]) {
+ dpb_buffer_.ref_valid[i] = 0;
}
}
}
@@ -839,7 +933,7 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
p_frame_header->delta_frame_id_minus_1 = Parser::ReadBits(p_stream, offset, p_seq_header->delta_frame_id_length_minus_2 + 2);
uint32_t delta_frame_id = p_frame_header->delta_frame_id_minus_1 + 1;
p_frame_header->expected_frame_id[i] = ((p_frame_header->current_frame_id + (1 << frame_id_len) - delta_frame_id ) % (1 << frame_id_len));
- if (p_frame_header->expected_frame_id[i] != ref_frame_id_[p_frame_header->ref_frame_idx[i]] || ref_valid_[p_frame_header->ref_frame_idx[i]] == 0) {
+ if (p_frame_header->expected_frame_id[i] != dpb_buffer_.ref_frame_id[p_frame_header->ref_frame_idx[i]] || dpb_buffer_.ref_valid[p_frame_header->ref_frame_idx[i]] == 0) {
ERR("Syntax Error: Reference buffer frame ID mismatch.\n");
return PARSER_INVALID_ARG;
}
@@ -875,7 +969,7 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
for (i = 0; i < REFS_PER_FRAME; i++) {
uint32_t ref_frame = kLastFrame + i;
- uint32_t hint = ref_order_hint_[p_frame_header->ref_frame_idx[i]];
+ uint32_t hint = dpb_buffer_.ref_order_hint[p_frame_header->ref_frame_idx[i]];
p_frame_header->order_hints[ref_frame] = hint;
if (!p_seq_header->enable_order_hint) {
p_frame_header->ref_frame_sign_bias[ref_frame] = 0;
@@ -891,20 +985,6 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
new_seq_activated_ = true;
}
- // Generate reference map for the next picture
- int ref_index = 0;
- for (int mask = p_frame_header->refresh_frame_flags; mask; mask >>= 1) {
- if (mask & 1) {
- ref_pic_map_next_[ref_index] = new_fb_index_;
- } else {
- ref_pic_map_next_[ref_index] = ref_pic_map_[ref_index];
- }
- ++ref_index;
- }
- for (; ref_index < NUM_REF_FRAMES; ++ref_index) {
- ref_pic_map_next_[ref_index] = ref_pic_map_[ref_index];
- }
-
if (p_seq_header->reduced_still_picture_header || p_frame_header->disable_cdf_update) {
p_frame_header->disable_frame_end_update_cdf = 1;
} else {
@@ -987,13 +1067,6 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
GlobalMotionParams(p_stream, offset, p_frame_header);
FilmGrainParams(p_stream, offset, p_seq_header, p_frame_header);
- // Update reference frames
- for (i = 0; i < NUM_REF_FRAMES; i++) {
- if ((p_frame_header->refresh_frame_flags >> i) & 1) {
- ref_order_hint_[i] = p_frame_header->order_hint;
- }
- }
-
*p_bytes_parsed = (offset + 7) >> 3;
return PARSER_OK;
}
@@ -1132,14 +1205,14 @@ void Av1VideoParser::MarkRefFrames(Av1SequenceHeader *p_seq_header, Av1FrameHead
int diff_len = p_seq_header->delta_frame_id_length_minus_2 + 2;
for (int i = 0; i < NUM_REF_FRAMES; i++) {
if (p_frame_header->frame_type == kKeyFrame && p_frame_header->show_frame) {
- ref_valid_[i] = 0;
+ dpb_buffer_.ref_valid[i] = 0;
} else if (p_frame_header->current_frame_id > (1 << diff_len)) {
- if (ref_frame_id_[i] > p_frame_header->current_frame_id || ref_frame_id_[i] < (p_frame_header->current_frame_id - (1 << diff_len))) {
- ref_valid_[i] = 0;
+ if (dpb_buffer_.ref_frame_id[i] > p_frame_header->current_frame_id || dpb_buffer_.ref_frame_id[i] < (p_frame_header->current_frame_id - (1 << diff_len))) {
+ dpb_buffer_.ref_valid[i] = 0;
}
} else {
- if (ref_frame_id_[i] > p_frame_header->current_frame_id && ref_frame_id_[i] < ((1 << id_len) + p_frame_header->current_frame_id - (1 << diff_len))) {
- ref_valid_[ i ] = 0;
+ if (dpb_buffer_.ref_frame_id[i] > p_frame_header->current_frame_id && dpb_buffer_.ref_frame_id[i] < ((1 << id_len) + p_frame_header->current_frame_id - (1 << diff_len))) {
+ dpb_buffer_.ref_valid[ i ] = 0;
}
}
}
@@ -1215,7 +1288,7 @@ void Av1VideoParser::SetFrameRefs(Av1SequenceHeader *p_seq_header, Av1FrameHeade
curr_frame_hint = 1 << (p_seq_header->order_hint_bits - 1);
for (i = 0; i < NUM_REF_FRAMES; i++) {
- shifted_order_hints[i] = curr_frame_hint + GetRelativeDist(p_seq_header, ref_order_hint_[i], p_frame_header->order_hint);
+ shifted_order_hints[i] = curr_frame_hint + GetRelativeDist(p_seq_header, dpb_buffer_.ref_order_hint[i], p_frame_header->order_hint);
}
// The kAltRefFrame reference is set to be a backward reference to the frame with highest output order.
@@ -1733,16 +1806,20 @@ void Av1VideoParser::CdefParams(const uint8_t *p_stream, size_t &offset, Av1Sequ
for (int i = 0; i < (1 << p_frame_header->cdef_params.cdef_bits); i++) {
p_frame_header->cdef_params.cdef_y_pri_strength[i] = Parser::ReadBits(p_stream, offset, 4);
p_frame_header->cdef_params.cdef_y_sec_strength[i] = Parser::ReadBits(p_stream, offset, 2);
+ /* Note: cdef_y_sec_strength is to be packed into the lower 2 bits of cdef_y_strengths, same way as in coded stream.
+ VA-VPI driver or below is expected to do the conditional increment, which we skip here.
if (p_frame_header->cdef_params.cdef_y_sec_strength[i] == 3) {
p_frame_header->cdef_params.cdef_y_sec_strength[i] += 1;
- }
+ }*/
if (p_seq_header->color_config.num_planes > 1) {
p_frame_header->cdef_params.cdef_uv_pri_strength[i] = Parser::ReadBits(p_stream, offset, 4);
p_frame_header->cdef_params.cdef_uv_sec_strength[i] = Parser::ReadBits(p_stream, offset, 2);
+ /* Note: cdef_uv_sec_strength is to be packed into the lower 2 bits of cdef_uv_strengths, same way as in coded stream.
+ VA-VPI driver or below is expected to do the conditional increment, which we skip here.
if (p_frame_header->cdef_params.cdef_uv_sec_strength[i] == 3) {
p_frame_header->cdef_params.cdef_uv_sec_strength[i] += 1;
- }
+ }*/
}
}
}
@@ -1820,11 +1897,11 @@ void Av1VideoParser::SkipModeParams(const uint8_t *p_stream, size_t &offset, Av1
} else {
forward_idx = -1;
backward_idx = -1;
- forward_hint = ref_order_hint_[0]; // init value. No effect.
- backward_hint = ref_order_hint_[1]; // init value. No effect.
+ forward_hint = dpb_buffer_.ref_order_hint[0]; // init value. No effect.
+ backward_hint = dpb_buffer_.ref_order_hint[1]; // init value. No effect.
for (i = 0; i < REFS_PER_FRAME; i++) {
- ref_hint = ref_order_hint_[p_frame_header->ref_frame_idx[i]];
+ ref_hint = dpb_buffer_.ref_order_hint[p_frame_header->ref_frame_idx[i]];
if (GetRelativeDist(p_seq_header, ref_hint, p_frame_header->order_hint ) < 0) {
if (forward_idx < 0 || GetRelativeDist(p_seq_header, ref_hint, forward_hint) > 0) {
forward_idx = i;
@@ -1846,9 +1923,9 @@ void Av1VideoParser::SkipModeParams(const uint8_t *p_stream, size_t &offset, Av1
p_frame_header->skip_mode_params.skip_mode_frame[1] = kLastFrame + std::max(forward_idx, backward_idx);
} else {
second_forward_idx = -1;
- second_forward_hint = ref_order_hint_[0]; // init value. No effect.
+ second_forward_hint = dpb_buffer_.ref_order_hint[0]; // init value. No effect.
for (i = 0; i < REFS_PER_FRAME; i++) {
- ref_hint = ref_order_hint_[p_frame_header->ref_frame_idx[i]];
+ ref_hint = dpb_buffer_.ref_order_hint[p_frame_header->ref_frame_idx[i]];
if (GetRelativeDist(p_seq_header, ref_hint, forward_hint ) < 0) {
if (second_forward_idx < 0 || GetRelativeDist(p_seq_header, ref_hint, second_forward_hint ) > 0) {
second_forward_idx = i;
diff --git a/projects/rocdecode/src/parser/av1_parser.h b/projects/rocdecode/src/parser/av1_parser.h
index b1f54e2098..8240ad70ac 100644
--- a/projects/rocdecode/src/parser/av1_parser.h
+++ b/projects/rocdecode/src/parser/av1_parser.h
@@ -75,10 +75,28 @@ public:
typedef struct {
int pic_idx;
int dec_buf_idx; // frame index in decode buffer pool
+ uint32_t current_frame_id;
+ uint32_t order_hint;
+ uint32_t frame_type;
uint32_t use_status; // refer to FrameBufUseStatus
- uint32_t pic_output_flag; // OutputFlag
+ uint32_t show_frame;
} Av1Picture;
+ /*! \brief Decoded picture buffer
+ */
+ typedef struct {
+ Av1Picture frame_store[BUFFER_POOL_MAX_SIZE]; // BufferPool
+ int dec_ref_count[BUFFER_POOL_MAX_SIZE]; // DecoderRefCount
+ // 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.
+ int virtual_buffer_index[NUM_REF_FRAMES]; // VBI
+ int ref_frame_type[NUM_REF_FRAMES];
+ int ref_frame_id[NUM_REF_FRAMES];
+ int ref_order_hint[NUM_REF_FRAMES];
+ int ref_valid[NUM_REF_FRAMES];
+ } DecodedPictureBuffer;
+
protected:
Av1ObuHeader obu_header_;
uint64_t obu_size_; // current OBU size in byte, not including header and size bytes
@@ -93,25 +111,9 @@ protected:
int temporal_id_; // temporal level of the data contained in the OBU
int spatial_id_; // spatial level of the data contained in the OBU
- // Frame header syntax elements
- int ref_frame_type_[NUM_REF_FRAMES];
- int ref_frame_id_[NUM_REF_FRAMES];
- int ref_order_hint_[NUM_REF_FRAMES];
- int ref_valid_[NUM_REF_FRAMES];
-
- // 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.
- int ref_pic_map_[NUM_REF_FRAMES];
- int ref_pic_map_next_[NUM_REF_FRAMES]; // for next picture
-
+ DecodedPictureBuffer dpb_buffer_;
Av1Picture curr_pic_;
- // The reference list for the current picture
- Av1Picture ref_pictures_[REFS_PER_FRAME];
- // The free frame buffer in DPB pool that the current picutre is decoded into
- int new_fb_index_;
-
uint32_t prev_gm_params_[NUM_REF_FRAMES][6];
/*! \brief Function to parse one picture bit stream received from the demuxer.
@@ -133,11 +135,31 @@ protected:
*/
ParserResult SendPicForDecode();
+ /*! Function to initialize the local DPB (BufferPool)
+ * \return None
+ */
+ void InitDpb();
+
+ /*! \brief Function to send out the remaining pictures that need for output in decode frame buffer.
+ * \return ParserResult
+ */
+ ParserResult FlushDpb();
+
+ /*! \brief Function to do reference frame update process. 7.20.
+ * \return None
+ */
+ void UpdateRefFrames();
+
/*! \brief Function to find a free buffer in the decode buffer pool
* \return ParserResult
*/
ParserResult FindFreeInDecBufPool();
+ /*! \brief Function to find a free buffer in DPB for the current picture and mark it.
+ * \return ParserResult
+ */
+ ParserResult FindFreeInDpbAndMark();
+
/*! \brief Function to parse an OBU header
* \param [in] p_stream Pointer to the bit stream
* \return ParserResult