diff --git a/src/parser/av1_defines.h b/src/parser/av1_defines.h
index 1aadf65421..2159caa75f 100644
--- a/src/parser/av1_defines.h
+++ b/src/parser/av1_defines.h
@@ -56,6 +56,7 @@ THE SOFTWARE.
#define SUPERRES_DENOM_BITS 3 // Number of bits sent to specify denominator of upscaling ratio
#define MAX_SEGMENTS 8 // Number of segments allowed in segmentation map
+#define SEG_LVL_ALT_Q 0 // Index for quantizer segment feature
#define SEG_LVL_REF_FRAME 5 // Index for reference frame segment feature
#define SEG_LVL_MAX 8 // Number of segment features
@@ -333,7 +334,7 @@ typedef struct {
typedef struct {
uint32_t frame_restoration_type[3];
uint32_t uses_lr;
- uint32_t lr_type;
+ uint32_t lr_type[3];
uint32_t lr_unit_shift;
uint32_t lr_unit_extra_shift;
uint32_t loop_restoration_size[3];
@@ -357,7 +358,6 @@ typedef struct {
typedef struct {
uint32_t gm_type[NUM_REF_FRAMES];
uint32_t gm_params[NUM_REF_FRAMES][6];
- uint32_t prev_gm_params[NUM_REF_FRAMES][6];
uint32_t is_global;
uint32_t is_rot_zoom;
uint32_t is_translation;
diff --git a/src/parser/av1_parser.cpp b/src/parser/av1_parser.cpp
index e106111880..8aca6bbcb3 100644
--- a/src/parser/av1_parser.cpp
+++ b/src/parser/av1_parser.cpp
@@ -24,7 +24,7 @@ THE SOFTWARE.
#include "av1_parser.h"
Av1VideoParser::Av1VideoParser() {
- //todo: add constructor code
+ seen_frame_header_ = 0;
}
Av1VideoParser::~Av1VideoParser() {
@@ -39,16 +39,137 @@ rocDecStatus Av1VideoParser::UnInitialize() {
}
rocDecStatus Av1VideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
- //to be implemented
- return ROCDEC_NOT_IMPLEMENTED;
+ if (p_data->payload && p_data->payload_size) {
+ if (ParsePictureData(p_data->payload, p_data->payload_size) != PARSER_OK) {
+ ERR(STR("Parser failed!"));
+ return ROCDEC_RUNTIME_ERROR;
+ }
+ pic_count_++;
+ } else if (!(p_data->flags & ROCDEC_PKT_ENDOFSTREAM)) {
+ // If no payload and EOS is not set, treated as invalid.
+ return ROCDEC_INVALID_PARAMETER;
+ }
+ return ROCDEC_SUCCESS;
}
-void Av1VideoParser::ParseSequenceHeader(uint8_t *p_stream, size_t size) {
+ParserResult Av1VideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t pic_data_size) {
+ ParserResult ret = PARSER_OK;
+ pic_data_buffer_ptr_ = (uint8_t*)p_stream;
+ pic_data_size_ = pic_data_size;
+ curr_byte_offset_ = 0;
+
+ while (ReadObuHeaderAndSize() != PARSER_EOF) {
+ switch (obu_header_.obu_type) {
+ case kObuTemporalDelimiter: {
+ seen_frame_header_ = 0;
+ break;
+ }
+ case kObuSequenceHeader: {
+ ParseSequenceHeaderObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_);
+ break;
+ }
+ case kObuFrameHeader: {
+ if (seen_frame_header_ != 0) {
+ ERR("If obu_type is equal to OBU_FRAME_HEADER, it is a requirement of bitstream conformance that SeenFrameHeader is equal to 0.");
+ return PARSER_INVALID_ARG;
+ }
+ int bytes_parsed;
+ if ((ret = ParseFrameHeaderObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_, &bytes_parsed)) != PARSER_OK) {
+ return ret;
+ }
+ break;
+ }
+ case kObuRedundantFrameHeader: {
+ if (seen_frame_header_ != 1) {
+ ERR("If obu_type is equal to OBU_REDUNDANT_FRAME_HEADER, it is a requirement of bitstream conformance that SeenFrameHeader is equal to 1.");
+ return PARSER_INVALID_ARG;
+ }
+ int bytes_parsed;
+ if ((ret = ParseFrameHeaderObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_, &bytes_parsed)) != PARSER_OK) {
+ return ret;
+ }
+ break;
+ }
+ case kObuFrame: {
+ int bytes_parsed;
+ if ((ret = ParseFrameHeaderObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_, &bytes_parsed)) != PARSER_OK) {
+ return ret;
+ }
+ obu_byte_offset_ += bytes_parsed;
+ if (obu_size_ > bytes_parsed) {
+ obu_size_ -= bytes_parsed;
+ ParseTileGroupObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_);
+ } else {
+ ERR("Frame OBU size error.");
+ return PARSER_OUT_OF_RANGE;
+ }
+ break;
+ }
+ case kObuTileGroup: {
+ ParseTileGroupObu(pic_data_buffer_ptr_ + obu_byte_offset_, obu_size_);
+ break;
+ }
+ default:
+ break;
+ }
+ };
+ return PARSER_OK;
+}
+
+ParserResult Av1VideoParser::ParseObuHeader(const uint8_t *p_stream) {
+ size_t offset = 0;
+ obu_header_.size = 1;
+ if (Parser::GetBit(p_stream, offset) != 0) {
+ ERR("Syntax error: obu_forbidden_bit must be set to 0.");
+ return PARSER_INVALID_ARG;
+ }
+ obu_header_.obu_type = Parser::ReadBits(p_stream, offset, 4);
+ obu_header_.obu_extension_flag = Parser::GetBit(p_stream, offset);
+ obu_header_.obu_has_size_field = Parser::GetBit(p_stream, offset);
+ if (!obu_header_.obu_has_size_field) {
+ ERR("Syntax error: Section 5.2: obu_has_size_field must be equal to 1.");
+ return PARSER_INVALID_ARG;
+ }
+ if (Parser::GetBit(p_stream, offset) != 0) {
+ ERR("Syntax error: obu_reserved_1bit must be set to 0.");
+ return PARSER_INVALID_ARG;
+ }
+ if (obu_header_.obu_extension_flag) {
+ obu_header_.size += 1;
+ obu_header_.temporal_id = Parser::ReadBits(p_stream, offset, 3);
+ obu_header_.spatial_id = Parser::ReadBits(p_stream, offset, 2);
+ if (Parser::ReadBits(p_stream, offset, 3) != 0) {
+ ERR("Syntax error: extension_header_reserved_3bits must be set to 0.\n");
+ return PARSER_INVALID_ARG;
+ }
+ }
+ return PARSER_OK;
+}
+
+ParserResult Av1VideoParser::ReadObuHeaderAndSize() {
+ ParserResult ret = PARSER_OK;
+ if (curr_byte_offset_ >= pic_data_size_) {
+ return PARSER_EOF;
+ }
+ uint8_t *p_stream = pic_data_buffer_ptr_ + curr_byte_offset_;
+ if ((ret = ParseObuHeader(p_stream)) != PARSER_OK) {
+ return ret;
+ }
+ curr_byte_offset_ += obu_header_.size;
+ p_stream += obu_header_.size;
+
+ uint32_t bytes_read;
+ obu_size_ = ReadLeb128(p_stream, &bytes_read);
+ obu_byte_offset_ = curr_byte_offset_ + bytes_read;
+ curr_byte_offset_ = obu_byte_offset_ + obu_size_;
+ return PARSER_OK;
+}
+
+void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
Av1SequenceHeader *p_seq_header = &seq_header_;
size_t offset = 0; // current bit offset
memset(p_seq_header, 0, sizeof(Av1SequenceHeader));
-
p_seq_header->seq_profile = Parser::ReadBits(p_stream, offset, 3);
p_seq_header->still_picture = Parser::GetBit(p_stream, offset);
p_seq_header->reduced_still_picture_header = Parser::GetBit(p_stream, offset);
@@ -194,7 +315,27 @@ void Av1VideoParser::ParseSequenceHeader(uint8_t *p_stream, size_t size) {
p_seq_header->film_grain_params_present = Parser::GetBit(p_stream, offset);
}
-ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t size) {
+ParserResult Av1VideoParser::ParseFrameHeaderObu(uint8_t *p_stream, size_t size, int *p_bytes_parsed) {
+ if (seen_frame_header_ == 1) {
+ // frame_header_copy(). Use the existing frame_header_obu
+ } else {
+ seen_frame_header_ = 1;
+ ParserResult ret;
+ if ((ret = ParseUncompressedHeader(p_stream, size, p_bytes_parsed)) != PARSER_OK) {
+ return ret;
+ }
+ if (frame_header_.show_existing_frame) {
+ // decode_frame_wrapup()
+ seen_frame_header_ = 0;
+ } else {
+ tile_num_ = 0;
+ seen_frame_header_ = 1;
+ }
+ }
+ return PARSER_OK;
+}
+
+ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t size, int *p_bytes_parsed) {
size_t offset = 0; // current bit offset
Av1SequenceHeader *p_seq_header = &seq_header_;
Av1FrameHeader *p_frame_header = &frame_header_;
@@ -203,7 +344,6 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
int i;
memset(p_frame_header, 0, sizeof(Av1FrameHeader));
-
if (p_seq_header->frame_id_numbers_present_flag) {
frame_id_len = p_seq_header->additional_frame_id_length_minus_1 + p_seq_header-> delta_frame_id_length_minus_2 + 3;
}
@@ -448,46 +588,37 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
}
if (p_frame_header->primary_ref_frame == PRIMARY_REF_NONE) {
- // Todo
- ERR("Warning: need to implement init_non_coeff_cdfs()\n");
-
+ // Todo: check need for implementation
+ //init_non_coeff_cdfs();
SetupPastIndependence(p_frame_header);
} else {
- // Todo
- ERR("Warning: need to implement load_cdfs()\n");
- ERR("Warning: need to implement load_previous()\n");
- return PARSER_NOT_IMPLEMENTED;
+ // Todo: check need for implementation
+ //load_cdfs();
+ //load_previous();
}
if (p_frame_header->use_ref_frame_mvs == 1) {
- // Todo
- ERR("Warning: need to implement motion_field_estimation()\n");
- return PARSER_NOT_IMPLEMENTED;
+ // Todo: check need for implementation
+ //motion_field_estimation());
}
TileInfo(p_stream, offset, p_seq_header, p_frame_header);
-
QuantizationParams(p_stream, offset, p_seq_header, p_frame_header);
-
SegmentationParams(p_stream, offset, p_frame_header);
-
DeltaQParams(p_stream, offset, p_frame_header);
-
DeltaLFParams(p_stream, offset, p_frame_header);
if (p_frame_header->primary_ref_frame == PRIMARY_REF_NONE) {
- // Todo
- ERR("Warning: Need to implement init_coeff_cdfs()\n");
+ // Todo: check need for implementation
+ // init_coeff_cdfs();
} else {
- // Todo
- ERR("Warning: Need to implement load_previous_segment_ids()\n");
+ // Todo: check need for implementation
+ //load_previous_segment_ids();
}
p_frame_header->coded_lossless = 1;
for (int segment_id = 0; segment_id < MAX_SEGMENTS; segment_id++) {
- // Todo int qindex = get_qindex( 1, segment_id );
- ERR("Warning: Need to implement get_qindex()\n");
- int qindex = 1;
+ int qindex = GetQIndex(p_frame_header, 1, segment_id);
p_frame_header->lossless_array[segment_id] = qindex == 0 && p_frame_header->quantization_params.delta_q_y_dc == 0 && p_frame_header->quantization_params.delta_q_u_ac == 0 && p_frame_header->quantization_params.delta_q_u_dc == 0 && p_frame_header->quantization_params.delta_q_v_ac == 0 && p_frame_header->quantization_params.delta_q_v_dc == 0;
if (!p_frame_header->lossless_array[segment_id]) {
p_frame_header->coded_lossless = 0;
@@ -508,11 +639,8 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
p_frame_header->all_lossless = p_frame_header->coded_lossless && (p_frame_header->frame_size.frame_width == p_frame_header->frame_size.upscaled_width);
LoopFilterParams(p_stream, offset, p_seq_header, p_frame_header);
-
CdefParams(p_stream, offset, p_seq_header, p_frame_header);
-
LrParams(p_stream, offset, p_seq_header, p_frame_header);
-
ReadTxMode(p_stream, offset, p_frame_header);
// frame_reference_mode()
@@ -533,13 +661,20 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
p_frame_header->reduced_tx_set = Parser::GetBit(p_stream, offset);
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;
}
-void Av1VideoParser::ParseTileGroupInfo(uint8_t *p_stream, size_t size) {
+void Av1VideoParser::ParseTileGroupObu(uint8_t *p_stream, size_t size) {
size_t offset = 0; // current bit offset
Av1SequenceHeader *p_seq_header = &seq_header_;
Av1FrameHeader *p_frame_header = &frame_header_;
@@ -590,6 +725,14 @@ void Av1VideoParser::ParseTileGroupInfo(uint8_t *p_stream, size_t size) {
p_tg_buf += tile_size + tile_size_bytes;
}
}
+
+ if (tg_end == num_tiles - 1) {
+ if (!frame_header_.disable_frame_end_update_cdf) {
+ //frame_end_update_cdf();
+ }
+ //decode_frame_wrapup();
+ seen_frame_header_ = 0;
+ }
}
void Av1VideoParser::ParseColorConfig(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header) {
@@ -689,27 +832,23 @@ void Av1VideoParser::FrameSize(const uint8_t *p_stream, size_t &offset, Av1Seque
p_frame_header->frame_size.frame_width = p_seq_header->max_frame_width_minus_1 + 1;
p_frame_header->frame_size.frame_height = p_seq_header->max_frame_height_minus_1 + 1;
}
-
SuperResParams(p_stream, offset, p_seq_header, p_frame_header);
ComputeImageSize(p_frame_header);
}
void Av1VideoParser::SuperResParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
uint32_t super_res_denom;
-
if (p_seq_header->enable_superres) {
p_frame_header->frame_size.superres_params.use_superres = Parser::GetBit(p_stream, offset);
} else {
p_frame_header->frame_size.superres_params.use_superres = 0;
}
-
if (p_frame_header->frame_size.superres_params.use_superres) {
p_frame_header->frame_size.superres_params.coded_denom = Parser::ReadBits(p_stream, offset, SUPERRES_DENOM_BITS);
super_res_denom = p_frame_header->frame_size.superres_params.coded_denom + SUPERRES_DENOM_MIN;
} else {
super_res_denom = SUPERRES_NUM;
}
-
p_frame_header->frame_size.upscaled_width = p_frame_header->frame_size.frame_width;
p_frame_header->frame_size.frame_width = (p_frame_header->frame_size.upscaled_width * SUPERRES_NUM + (super_res_denom / 2)) / super_res_denom;
}
@@ -888,11 +1027,31 @@ void Av1VideoParser::FrameSizeWithRefs(const uint8_t *p_stream, size_t &offset,
}
void Av1VideoParser::SetupPastIndependence(Av1FrameHeader *p_frame_header) {
- p_frame_header->loop_filter_params.loop_filter_delta_enabled = 1;
- p_frame_header->loop_filter_params.loop_filter_delta_update = 1;
+ for (int i = 0; i < MAX_SEGMENTS; i++) {
+ for (int j = 0; j < SEG_LVL_MAX; j++) {
+ p_frame_header->segmentation_params.feature_data[i][j] = 0;
+ p_frame_header->segmentation_params.feature_enabled_flags[i][j] = 0;
+ }
+ }
+ // Block level: PrevSegmentIds[ row ][ col ] is set equal to 0 for row = 0..MiRows-1 and col = 0..MiCols-1.
+ for (int ref = kLastFrame; ref <= kAltRefFrame; ref++) {
+ p_frame_header->global_motion_params.gm_type[ref] = kIdentity;
+ for (int i = 0; i < 6; i++) {
+ prev_gm_params_[ref][i] = (i % 3 == 2) ? 1 << WARPEDMODEL_PREC_BITS : 0;
+ }
+ }
- // Todo
- ERR("Need to implement the rest of SetupPastIndependence");
+ p_frame_header->loop_filter_params.loop_filter_delta_enabled = 1;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kIntraFrame] = 1;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kLastFrame] = 0;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kLast2Frame] = 0;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kLast3Frame] = 0;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kBwdRefFrame] = 0;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kGoldenFrame] = -1;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kAltRefFrame] = -1;
+ p_frame_header->loop_filter_params.loop_filter_ref_deltas[kAltRef2Frame] = -1;
+ p_frame_header->loop_filter_params.loop_filter_mode_deltas[0] = 0;
+ p_frame_header->loop_filter_params.loop_filter_mode_deltas[1] = 0;
}
void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
@@ -1012,8 +1171,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
uint32_t Av1VideoParser::TileLog2(uint32_t blk_size, uint32_t target) {
uint32_t k;
- for (k = 0; (blk_size << k) < target; k++ ) {
- }
+ for (k = 0; (blk_size << k) < target; k++ ) {}
return k;
}
@@ -1137,12 +1295,10 @@ void Av1VideoParser::SegmentationParams(const uint8_t *p_stream, size_t &offset,
void Av1VideoParser::DeltaQParams(const uint8_t *p_stream, size_t &offset, Av1FrameHeader *p_frame_header) {
p_frame_header->delta_q_params.delta_q_res = 0;
p_frame_header->delta_q_params.delta_q_present = 0;
- if ( p_frame_header->quantization_params.base_q_idx > 0 )
- {
+ if (p_frame_header->quantization_params.base_q_idx > 0) {
p_frame_header->delta_q_params.delta_q_present = Parser::GetBit(p_stream, offset);
}
- if ( p_frame_header->delta_q_params.delta_q_present )
- {
+ if (p_frame_header->delta_q_params.delta_q_present) {
p_frame_header->delta_q_params.delta_q_res = Parser::ReadBits(p_stream, offset, 2);
}
}
@@ -1162,6 +1318,22 @@ void Av1VideoParser::DeltaLFParams(const uint8_t *p_stream, size_t &offset, Av1F
}
}
+int Av1VideoParser::GetQIndex(Av1FrameHeader *p_frame_header, int ignore_delta_q, int segment_id) {
+ // seg_feature_active_idx(segment_id, SEG_LVL_ALT_Q)
+ int seg_feature_active_idx = p_frame_header->segmentation_params.segmentation_enabled && p_frame_header->segmentation_params.feature_enabled_flags[segment_id][SEG_LVL_ALT_Q];
+ if (seg_feature_active_idx == 1) {
+ int data = p_frame_header->segmentation_params.feature_data[segment_id][SEG_LVL_ALT_Q];
+ int q_index = p_frame_header->quantization_params.base_q_idx + data;
+ // CurrentQIndex is base_q_idx at tile level: If ignoreDeltaQ is equal to 0 and delta_q_present is equal to 1, set qindex equal to CurrentQIndex + data.
+ std::clamp(q_index, 0, 255);
+ return q_index;
+ } else if (ignore_delta_q == 0 && p_frame_header->delta_q_params.delta_q_present == 1) {
+ return p_frame_header->quantization_params.base_q_idx; // CurrentQIndex is base_q_idx at tile level
+ } else {
+ return p_frame_header->quantization_params.base_q_idx;
+ }
+}
+
void Av1VideoParser::LoopFilterParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
int i;
@@ -1258,8 +1430,8 @@ void Av1VideoParser::LrParams(const uint8_t *p_stream, size_t &offset, Av1Sequen
p_frame_header->lr_params.uses_lr = 0;
uint32_t uses_chroma_lr = 0;
for (int i = 0; i < p_seq_header->color_config.num_planes; i++) {
- p_frame_header->lr_params.lr_type = Parser::ReadBits(p_stream, offset, 2);
- p_frame_header->lr_params.frame_restoration_type[i] = remap_lr_type[p_frame_header->lr_params.lr_type];
+ p_frame_header->lr_params.lr_type[i] = Parser::ReadBits(p_stream, offset, 2);
+ p_frame_header->lr_params.frame_restoration_type[i] = remap_lr_type[p_frame_header->lr_params.lr_type[i]];
if (p_frame_header->lr_params.frame_restoration_type[i] != kRestoreNone) {
p_frame_header->lr_params.uses_lr = 1;
if (i > 0) {
@@ -1299,7 +1471,7 @@ void Av1VideoParser::ReadTxMode(const uint8_t *p_stream, size_t &offset, Av1Fram
if (p_frame_header->tx_mode.tx_mode_select) {
p_frame_header->tx_mode.tx_mode = kTxModeSelect;
} else {
- p_frame_header->tx_mode.tx_mode = kTxModeSelect;
+ p_frame_header->tx_mode.tx_mode = kTxModeLargest;
}
}
}
@@ -1380,7 +1552,6 @@ void Av1VideoParser::GlobalMotionParams(const uint8_t *p_stream, size_t &offset,
p_frame_header->global_motion_params.gm_params[ref][i] = ( ( i % 3 == 2 ) ? 1 << WARPEDMODEL_PREC_BITS : 0 );
}
}
-
if (p_frame_header->frame_is_intra) {
return;
}
@@ -1411,7 +1582,6 @@ void Av1VideoParser::GlobalMotionParams(const uint8_t *p_stream, size_t &offset,
p_frame_header->global_motion_params.gm_params[ref][5] = p_frame_header->global_motion_params.gm_params[ref][2];
}
}
-
if ( type >= kTranslation ) {
ReadGlobalParam(p_stream, offset, p_frame_header, type, ref, 0);
ReadGlobalParam(p_stream, offset, p_frame_header, type, ref, 1);
@@ -1432,14 +1602,11 @@ void Av1VideoParser::ReadGlobalParam(const uint8_t *p_stream, size_t &offset, Av
prec_bits = GM_TRANS_PREC_BITS;
}
}
-
int prec_diff = WARPEDMODEL_PREC_BITS - prec_bits;
int round = (idx % 3) == 2 ? (1 << WARPEDMODEL_PREC_BITS) : 0;
int sub = (idx % 3) == 2 ? (1 << prec_bits) : 0;
int mx = (1 << abs_bits);
- // Todo:
- ERR("Error: PrevGmParams is calculated in SetupPastIndependence() (setup_past_independence()) function, which is not implemented yet.\n");
- int r = (p_frame_header->global_motion_params.prev_gm_params[ref][idx] >> prec_diff) - sub;
+ int r = (prev_gm_params_[ref][idx] >> prec_diff) - sub;
p_frame_header->global_motion_params.gm_params[ref][idx] = (DecodeSignedSubexpWithRef(p_stream, offset, -mx, mx + 1, r) << prec_diff) + round;
}
diff --git a/src/parser/av1_parser.h b/src/parser/av1_parser.h
index 1dd85e5424..ba4b34dae0 100644
--- a/src/parser/av1_parser.h
+++ b/src/parser/av1_parser.h
@@ -72,9 +72,15 @@ public:
} Av1TileGroupDataInfo;
protected:
+ Av1ObuHeader obu_header_;
+ uint64_t obu_size_; // current OBU size in byte, not including header and size bytes
+ uint32_t obu_byte_offset_; // current OBU byte offset, not including header and obu_size syntax elements
+
+ uint32_t seen_frame_header_; // SeenFrameHeader
Av1SequenceHeader seq_header_;
Av1FrameHeader frame_header_;
Av1TileGroupDataInfo tile_group_data_;
+ uint32_t tile_num_;
int temporal_id_; // temporal level of the data contained in the OBU
int spatial_id_; // spatial level of the data contained in the OBU
@@ -96,26 +102,55 @@ protected:
// The free frame buffer in DPB pool that the current picutre is decoded into
int new_fb_index_;
- /*! \brief Function to parse a sequence header OBU
+ uint32_t prev_gm_params_[NUM_REF_FRAMES][6];
+
+ /*! \brief Function to parse one picture bit stream received from the demuxer.
+ * \param [in] p_stream A pointer of uint8_t for the input stream to be parsed
+ * \param [in] pic_data_size Size of the input stream
+ * \return ParserResult
+ */
+ ParserResult ParsePictureData(const uint8_t *p_stream, uint32_t pic_data_size);
+
+ /*! \brief Function to parse an OBU header
+ * \param [in] p_stream Pointer to the bit stream
+ * \return ParserResult
+ */
+ ParserResult ParseObuHeader(const uint8_t *p_stream);
+
+ /*! \brief Function to parse an OBU header and size
+ * \return ParserResult
+ */
+ ParserResult ReadObuHeaderAndSize();
+
+ /*! \brief Function to parse a sequence header OBU. 5.5.
* \param [in] p_stream Pointer to the bit stream
* \param [in] size Byte size of the stream
* \return None
*/
- void ParseSequenceHeader(uint8_t *p_stream, size_t size);
+ void ParseSequenceHeaderObu(uint8_t *p_stream, size_t size);
+
+ /*! \brief Function to parse a frame header OBU. 5.9.
+ * \param [in] p_stream Pointer to the bit stream
+ * \param [in] size Byte size of the stream
+ * \param [out] p_bytes_parsed Number of bytes that have been parsed
+ * \return None
+ */
+ ParserResult ParseFrameHeaderObu(uint8_t *p_stream, size_t size, int *p_bytes_parsed);
/*! \brief Function to parse a frame header OBU
* \param [in] p_stream Pointer to the bit stream
* \param [in] size Byte size of the stream
+ * \param [out] p_bytes_parsed Number of bytes that have been parsed
* \return ParserResult
*/
- ParserResult ParseUncompressedHeader(uint8_t *p_stream, size_t size);
+ ParserResult ParseUncompressedHeader(uint8_t *p_stream, size_t size, int *p_bytes_parsed);
/*! \brief Function to parse a tile group OBU
* \param [in] p_stream Pointer to the bit stream
* \param [in] size Byte size of the stream
* \return None
*/
- void ParseTileGroupInfo(uint8_t *p_stream, size_t size);
+ void ParseTileGroupObu(uint8_t *p_stream, size_t size);
/*! \brief Function to parse color config in sequence header
* \param [in] p_stream Pointer to the bit stream
@@ -286,6 +321,14 @@ protected:
*/
void DeltaLFParams(const uint8_t *p_stream, size_t &offset, Av1FrameHeader *p_frame_header);
+ /*! \brief Function to return the quantizer index for the current block
+ * \param [in] p_frame_header Pointer to frame header struct
+ * \param [in] ignore_delta_q Indicator to ignore the Q index delta
+ * \param [in] segment_id Segment id
+ * \return Quantizer index
+ */
+ int GetQIndex(Av1FrameHeader *p_frame_header, int ignore_delta_q, int segment_id);
+
/*! \brief Function to parse loop filter parameters
* \param [in] p_stream Pointer to the bit stream
* \param [in] offset Starting bit offset
@@ -434,11 +477,11 @@ protected:
* \param [out] p_num_bytes_read Number of bytes read
* \return The unsigned value
*/
- inline uint32_t ReadLeb128(const uint8_t *p_stream, uint32_t *p_num_bytes_read) {
+ inline uint64_t ReadLeb128(const uint8_t *p_stream, uint32_t *p_num_bytes_read) {
uint32_t value = 0;
*p_num_bytes_read = 0;
uint32_t len;
- for (len = 0; len < 4; ++len) {
+ for (len = 0; len < 8; ++len) {
value |= (p_stream[len] & 0x7F) << (len * 7);
if ((p_stream[len] & 0x80) == 0) {
++len;