* 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: 54419dcca3]
Этот коммит содержится в:
jeffqjiangNew
2024-06-27 10:26:21 -04:00
коммит произвёл GitHub
родитель 5bdf7f6b8d
Коммит a13ce87a9b
3 изменённых файлов: 184 добавлений и 85 удалений
+1 -1
Просмотреть файл
@@ -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
+143 -66
Просмотреть файл
@@ -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;
+40 -18
Просмотреть файл
@@ -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 <tt>ParserResult</tt>
*/
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 <tt>ParserResult</tt>
*/
ParserResult FindFreeInDecBufPool();
/*! \brief Function to find a free buffer in DPB for the current picture and mark it.
* \return <tt>ParserResult</tt>
*/
ParserResult FindFreeInDpbAndMark();
/*! \brief Function to parse an OBU header
* \param [in] p_stream Pointer to the bit stream
* \return <tt>ParserResult</tt>