* AV1 error resilience: Added invalid stream syntax element checks in various places. (#582)

- Added checks for allowed values for various stream syntax elements, according to AV1 specification.
This commit is contained in:
jeffqjiangNew
2025-05-09 14:35:08 -04:00
committed by GitHub
parent b84146fb42
commit 17ef0c2d56
2 changed files with 117 additions and 23 deletions
+109 -15
View File
@@ -748,14 +748,19 @@ ParserResult Av1VideoParser::ReadObuHeaderAndSize() {
}
}
void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
ParserResult 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);
CHECK_ALLOWED_MAX("seq_profile", p_seq_header->seq_profile, 2);
p_seq_header->still_picture = Parser::GetBit(p_stream, offset);
p_seq_header->reduced_still_picture_header = Parser::GetBit(p_stream, offset);
if (p_seq_header->reduced_still_picture_header == 1 && p_seq_header->still_picture != 1) {
ERR("If reduced_still_picture_header is 1, still_picture is required to be 1.");
return PARSER_WRONG_STATE;
}
if (p_seq_header->reduced_still_picture_header) {
p_seq_header->timing_info_present_flag = 0;
@@ -772,7 +777,15 @@ void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
if (p_seq_header->timing_info_present_flag) {
// timing_info()
p_seq_header->timing_info.num_units_in_display_tick = Parser::ReadBits(p_stream, offset, 32);
if (p_seq_header->timing_info.num_units_in_display_tick == 0) {
ERR("num_units_in_display_tick is 0.");
return PARSER_WRONG_STATE;
}
p_seq_header->timing_info.time_scale = Parser::ReadBits(p_stream, offset, 32);
if (p_seq_header->timing_info.time_scale == 0) {
ERR("time_scale is 0.");
return PARSER_WRONG_STATE;
}
p_seq_header->timing_info.equal_picture_interval = Parser::GetBit(p_stream, offset);
if (p_seq_header->timing_info.equal_picture_interval) {
p_seq_header->timing_info.num_ticks_per_picture_minus_1 = ReadUVLC(p_stream, offset);
@@ -793,6 +806,18 @@ void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
p_seq_header->operating_points_cnt_minus_1 = Parser::ReadBits(p_stream, offset, 5);
for (int i = 0; i < p_seq_header->operating_points_cnt_minus_1 + 1; i++) {
p_seq_header->operating_point_idc[i] = Parser::ReadBits(p_stream, offset, 12);
if (i > 0) {
for (int j = 0; j < i - 1; j++) {
if (p_seq_header->operating_point_idc[i] == p_seq_header->operating_point_idc[j]) {
ERR("operating_point_idc[" + TOSTR(i) + "] is equal to operating_point_idc[" + TOSTR(j) + "]");
return PARSER_WRONG_STATE;
}
}
}
if (p_seq_header->operating_point_idc[i] && obu_header_.obu_extension_flag != 1) {
ERR("When operating_point_idc is not 0, obu_extension_flag is required to be 1.");
return PARSER_WRONG_STATE;
}
p_seq_header->seq_level_idx[i] = Parser::ReadBits(p_stream, offset, 5);
if (p_seq_header->seq_level_idx[i] > 7) {
p_seq_header->seq_tier[i] = Parser::GetBit(p_stream, offset);
@@ -901,6 +926,7 @@ void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
CheckAndAdjustDecBufPoolSize(BUFFER_POOL_MAX_SIZE * 2);
}
p_seq_header->is_received = 1;
return PARSER_OK;
}
ParserResult Av1VideoParser::ParseFrameHeaderObu(uint8_t *p_stream, size_t size, int *p_bytes_parsed) {
@@ -926,6 +952,7 @@ ParserResult Av1VideoParser::ParseFrameHeaderObu(uint8_t *p_stream, size_t size,
}
ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t size, int *p_bytes_parsed) {
ParserResult ret = PARSER_OK;
size_t offset = 0; // current bit offset
Av1SequenceHeader *p_seq_header = &seq_header_;
Av1FrameHeader *p_frame_header = &frame_header_;
@@ -952,6 +979,10 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
} else {
p_frame_header->show_existing_frame = Parser::GetBit(p_stream, offset);
if (p_frame_header->show_existing_frame == 1) {
if (obu_header_.obu_type == kObuFrame) {
ERR("show_existing_frame is 1 when obu_type is equal to OBU_FRAME.");
return PARSER_WRONG_STATE;
}
p_frame_header->frame_to_show_map_idx = Parser::ReadBits(p_stream, offset, 3);
if (p_seq_header->decoder_model_info_present_flag && !p_seq_header->timing_info.equal_picture_interval) {
// temporal_point_info()
@@ -959,6 +990,7 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
}
p_frame_header->refresh_frame_flags = 0;
if (p_seq_header->frame_id_numbers_present_flag) {
CHECK_ALLOWED_MAX("display_frame_id length", frame_id_len, 16);
p_frame_header->display_frame_id = Parser::ReadBits(p_stream, offset, frame_id_len);
}
p_frame_header->frame_type = dpb_buffer_.ref_frame_type[p_frame_header->frame_to_show_map_idx];
@@ -1067,6 +1099,10 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
p_frame_header->refresh_frame_flags = all_frames;
} else {
p_frame_header->refresh_frame_flags = Parser::ReadBits(p_stream, offset, 8);
if (p_frame_header->frame_type == kIntraOnlyFrame && p_frame_header->refresh_frame_flags == 0xFF) {
ERR("When frame_type is equal to INTRA_ONLY_FRAME, it is a requirement of bitstream conformance that refresh_frame_flags is not equal to 0xff.");
return PARSER_WRONG_STATE;
}
}
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) {
@@ -1080,7 +1116,9 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
}
if (p_frame_header->frame_is_intra) {
FrameSize(p_stream, offset, p_seq_header, p_frame_header);
if ((ret = FrameSize(p_stream, offset, p_seq_header, p_frame_header)) != PARSER_OK) {
return ret;
}
RenderSize(p_stream, offset, p_frame_header);
if (p_frame_header->allow_screen_content_tools && p_frame_header->frame_size.upscaled_width == p_frame_header->frame_size.frame_width) {
p_frame_header->allow_intrabc = Parser::GetBit(p_stream, offset);
@@ -1116,7 +1154,9 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
if (p_frame_header->frame_size_override_flag && !p_frame_header->error_resilient_mode) {
FrameSizeWithRefs(p_stream, offset, p_seq_header, p_frame_header);
} else {
FrameSize(p_stream, offset, p_seq_header, p_frame_header);
if ((ret = FrameSize(p_stream, offset, p_seq_header, p_frame_header)) != PARSER_OK) {
return ret;
}
RenderSize(p_stream, offset, p_frame_header);
}
@@ -1179,7 +1219,9 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
//motion_field_estimation());
}
TileInfo(p_stream, offset, p_seq_header, p_frame_header);
if ((ret = TileInfo(p_stream, offset, p_seq_header, p_frame_header)) != PARSER_OK) {
return ret;
}
QuantizationParams(p_stream, offset, p_seq_header, p_frame_header);
SegmentationParams(p_stream, offset, p_frame_header);
DeltaQParams(p_stream, offset, p_frame_header);
@@ -1212,6 +1254,10 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
}
}
}
if (p_frame_header->coded_lossless == 1 && p_frame_header->delta_q_params.delta_q_present == 1) {
ERR("It is a requirement of bitstream conformance that delta_q_present is equal to 0 when CodedLossless is equal to 1.");
return PARSER_WRONG_STATE;
}
p_frame_header->all_lossless = p_frame_header->coded_lossless && (p_frame_header->frame_size.frame_width == p_frame_header->frame_size.upscaled_width);
@@ -1238,7 +1284,9 @@ 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);
if ((ret = FilmGrainParams(p_stream, offset, p_seq_header, p_frame_header)) != PARSER_OK) {
return ret;
}
*p_bytes_parsed = (offset + 7) >> 3;
p_frame_header->is_received = 1;
@@ -1269,6 +1317,10 @@ ParserResult Av1VideoParser::ParseTileGroupObu(uint8_t *p_stream, size_t size) {
p_tile_group->num_tiles = tile_cols * tile_rows;
if (p_tile_group->num_tiles > 1) {
tile_start_and_end_present_flag = Parser::GetBit(p_stream, offset);
if (obu_header_.obu_type == kObuFrame && tile_start_and_end_present_flag != 0) {
ERR("If obu_type is equal to OBU_FRAME, it is a requirement of bitstream conformance that the value of tile_start_and_end_present_flag is equal to 0.");
return PARSER_WRONG_STATE;
}
}
if (p_tile_group->num_tiles == 1 || !tile_start_and_end_present_flag) {
p_tile_group->tg_start = 0;
@@ -1276,7 +1328,15 @@ ParserResult Av1VideoParser::ParseTileGroupObu(uint8_t *p_stream, size_t size) {
} else {
uint32_t tile_bits = p_frame_header->tile_info.tile_cols_log2 + p_frame_header->tile_info.tile_rows_log2;
p_tile_group->tg_start = Parser::ReadBits(p_stream, offset, tile_bits);
if (p_tile_group->tg_start != p_tile_group->num_tiles_parsed) {
ERR("It is a requirement of bitstream conformance that the value of tg_start (" + TOSTR(p_tile_group->tg_start) + ") is equal to the value of TileNum (" + TOSTR(p_tile_group->num_tiles_parsed) + ") at the point that tile_group_obu is invoked.");
return PARSER_WRONG_STATE;
}
p_tile_group->tg_end = Parser::ReadBits(p_stream, offset, tile_bits);
if (p_tile_group->tg_end < p_tile_group->tg_start) {
ERR("It is a requirement of bitstream conformance that the value of tg_end (" + TOSTR(p_tile_group->tg_end) + ") is greater than or equal to tg_start (" + TOSTR(p_tile_group->tg_start) + ").");
return PARSER_WRONG_STATE;
}
}
header_bytes = ((offset + 7) >> 3);
@@ -1379,12 +1439,10 @@ void Av1VideoParser::ParseColorConfig(const uint8_t *p_stream, size_t &offset, A
p_seq_header->color_config.subsampling_y = 0;
}
}
if (p_seq_header->color_config.subsampling_x && p_seq_header->color_config.subsampling_y) {
p_seq_header->color_config.chroma_sample_position = Parser::ReadBits(p_stream, offset, 2);
}
}
p_seq_header->color_config.separate_uv_delta_q = Parser::GetBit(p_stream, offset);
}
@@ -1405,11 +1463,13 @@ void Av1VideoParser::MarkRefFrames(Av1SequenceHeader *p_seq_header, Av1FrameHead
}
}
void Av1VideoParser::FrameSize(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
ParserResult Av1VideoParser::FrameSize(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
if (p_frame_header->frame_size_override_flag) {
p_frame_header->frame_size.frame_width_minus_1 = Parser::ReadBits(p_stream, offset, p_seq_header->frame_width_bits_minus_1 + 1);
CHECK_ALLOWED_MAX("frame_width_minus_1", p_frame_header->frame_size.frame_width_minus_1, p_seq_header->max_frame_width_minus_1);
p_frame_header->frame_size.frame_width = p_frame_header->frame_size.frame_width_minus_1 + 1;
p_frame_header->frame_size.frame_height_minus_1 = Parser::ReadBits(p_stream, offset, p_seq_header->frame_height_bits_minus_1 + 1);
CHECK_ALLOWED_MAX("frame_height_minus_1", p_frame_header->frame_size.frame_height_minus_1, p_seq_header->max_frame_height_minus_1);
p_frame_header->frame_size.frame_height = p_frame_header->frame_size.frame_height_minus_1 + 1;
} else {
p_frame_header->frame_size.frame_width_minus_1 = p_seq_header->max_frame_width_minus_1;
@@ -1419,6 +1479,7 @@ void Av1VideoParser::FrameSize(const uint8_t *p_stream, size_t &offset, Av1Seque
}
SuperResParams(p_stream, offset, p_seq_header, p_frame_header);
ComputeImageSize(p_frame_header);
return PARSER_OK;
}
void Av1VideoParser::SuperResParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
@@ -1655,7 +1716,7 @@ void Av1VideoParser::LoadPrevious(Av1FrameHeader *p_frame_header) {
}
}
void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
ParserResult Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
int32_t sb_cols;
int32_t sb_rows;
int32_t sb_shift;
@@ -1699,6 +1760,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
}
tile_width_sb = (sb_cols + (1 << p_frame_header->tile_info.tile_cols_log2) - 1) >> p_frame_header->tile_info.tile_cols_log2;
CHECK_ALLOWED_MAX("tileWidthSb", tile_width_sb, max_tile_width_sb);
i = 0;
for (start_sb = 0; start_sb < sb_cols; start_sb += tile_width_sb) {
p_frame_header->tile_info.mi_col_starts[i] = start_sb << sb_shift;
@@ -1706,6 +1768,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
p_frame_header->tile_info.mi_col_starts[i] = p_frame_header->frame_size.mi_cols;
p_frame_header->tile_info.tile_cols = i;
CHECK_ALLOWED_MAX("TileCols", p_frame_header->tile_info.tile_cols, MAX_TILE_COLS);
min_log2_tile_rows = std::max(min_log2_tiles - p_frame_header->tile_info.tile_cols_log2, 0);
p_frame_header->tile_info.tile_rows_log2 = min_log2_tile_rows;
@@ -1718,6 +1781,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
}
tile_height_sb = (sb_rows + (1 << p_frame_header->tile_info.tile_rows_log2) - 1) >> p_frame_header->tile_info.tile_rows_log2;
CHECK_ALLOWED_MAX("tileWidthSb * tileHeightSb", tile_width_sb * tile_height_sb, max_tile_area_sb);
i = 0;
for (start_sb = 0; start_sb < sb_rows; start_sb += tile_height_sb ) {
p_frame_header->tile_info.mi_row_starts[i] = start_sb << sb_shift;
@@ -1725,6 +1789,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
p_frame_header->tile_info.mi_row_starts[i] = p_frame_header->frame_size.mi_rows;
p_frame_header->tile_info.tile_rows = i;
CHECK_ALLOWED_MAX("TileRows", p_frame_header->tile_info.tile_rows, MAX_TILE_ROWS);
for (i = 0; i < p_frame_header->tile_info.tile_cols - 1; i++) {
p_frame_header->tile_info.width_in_sbs_minus_1[i] = tile_width_sb - 1;
@@ -1747,6 +1812,7 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
p_frame_header->tile_info.mi_col_starts[i] = p_frame_header->frame_size.mi_cols;
p_frame_header->tile_info.tile_cols = i;
CHECK_ALLOWED_MAX("TileCols", p_frame_header->tile_info.tile_cols, MAX_TILE_COLS);
p_frame_header->tile_info.tile_cols_log2 = TileLog2(1, p_frame_header->tile_info.tile_cols);
if (min_log2_tiles > 0) {
@@ -1766,15 +1832,18 @@ void Av1VideoParser::TileInfo(const uint8_t *p_stream, size_t &offset, Av1Sequen
}
p_frame_header->tile_info.mi_row_starts[ i ] = p_frame_header->frame_size.mi_rows;
p_frame_header->tile_info.tile_rows = i;
CHECK_ALLOWED_MAX("TileRows", p_frame_header->tile_info.tile_rows, MAX_TILE_ROWS);
p_frame_header->tile_info.tile_rows_log2 = TileLog2(1, p_frame_header->tile_info.tile_rows);
}
if (p_frame_header->tile_info.tile_cols_log2 > 0 || p_frame_header->tile_info.tile_rows_log2 > 0) {
p_frame_header->tile_info.context_update_tile_id = Parser::ReadBits(p_stream, offset, p_frame_header->tile_info.tile_rows_log2 + p_frame_header->tile_info.tile_cols_log2);
CHECK_ALLOWED_MAX("context_update_tile_id", p_frame_header->tile_info.context_update_tile_id, p_frame_header->tile_info.tile_cols * p_frame_header->tile_info.tile_rows);
p_frame_header->tile_info.tile_size_bytes_minus_1 = Parser::ReadBits(p_stream, offset, 2);
} else {
p_frame_header->tile_info.context_update_tile_id = 0;
}
return PARSER_OK;
}
uint32_t Av1VideoParser::TileLog2(uint32_t blk_size, uint32_t target) {
@@ -2338,20 +2407,19 @@ void Av1VideoParser::ResolveDivisor(int d, int *div_shift, int *div_factor) {
}
}
void Av1VideoParser::FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
ParserResult Av1VideoParser::FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header) {
int i;
if (!p_seq_header->film_grain_params_present || (!p_frame_header->show_frame && !p_frame_header->showable_frame)) {
// reset_grain_params()
memset(&p_frame_header->film_grain_params, 0, sizeof(Av1FilmGrainParams));
return;
return PARSER_OK;
}
p_frame_header->film_grain_params.apply_grain = Parser::GetBit(p_stream, offset);
if ( !p_frame_header->film_grain_params.apply_grain )
{
if (!p_frame_header->film_grain_params.apply_grain) {
// reset_grain_params()
memset(&p_frame_header->film_grain_params, 0, sizeof(Av1FilmGrainParams));
return;
return PARSER_OK;
}
p_frame_header->film_grain_params.grain_seed = Parser::ReadBits(p_stream, offset, 16);
@@ -2366,12 +2434,17 @@ void Av1VideoParser::FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av
int temp_grain_seed = p_frame_header->film_grain_params.grain_seed;
p_frame_header->film_grain_params = dpb_buffer_.saved_film_grain_params[p_frame_header->film_grain_params.film_grain_params_ref_idx]; // load_grain_params()
p_frame_header->film_grain_params.grain_seed = temp_grain_seed;
return;
return PARSER_OK;
}
p_frame_header->film_grain_params.num_y_points = Parser::ReadBits(p_stream, offset, 4);
CHECK_ALLOWED_MAX("num_y_points", p_frame_header->film_grain_params.num_y_points, 14);
for (i = 0; i < p_frame_header->film_grain_params.num_y_points; i++) {
p_frame_header->film_grain_params.point_y_value[i] = Parser::ReadBits(p_stream, offset, 8);
if (i > 0 && p_frame_header->film_grain_params.point_y_value[i] <= p_frame_header->film_grain_params.point_y_value[i - 1]) {
ERR("point_y_value["+ TOSTR(i) + "] (" + TOSTR(p_frame_header->film_grain_params.point_y_value[i]) + ") should be greater than point_y_value[" + TOSTR(i - 1) + "] (" + TOSTR(p_frame_header->film_grain_params.point_y_value[i - 1]) + ")");
return PARSER_INVALID_ARG;
}
p_frame_header->film_grain_params.point_y_scaling[i] = Parser::ReadBits(p_stream, offset, 8);
}
@@ -2386,14 +2459,34 @@ void Av1VideoParser::FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av
p_frame_header->film_grain_params.num_cr_points = 0;
} else {
p_frame_header->film_grain_params.num_cb_points = Parser::ReadBits(p_stream, offset, 4);
CHECK_ALLOWED_MAX("num_cb_points", p_frame_header->film_grain_params.num_cb_points, 10);
for (i = 0; i < p_frame_header->film_grain_params.num_cb_points; i++) {
p_frame_header->film_grain_params.point_cb_value[i] = Parser::ReadBits(p_stream, offset, 8);
if (i > 0 && p_frame_header->film_grain_params.point_cb_value[i] <= p_frame_header->film_grain_params.point_cb_value[i - 1]) {
ERR("point_cb_value["+ TOSTR(i) + "] (" + TOSTR(p_frame_header->film_grain_params.point_cb_value[i]) + ") should be greater than point_cb_value[" + TOSTR(i - 1) + "] (" + TOSTR(p_frame_header->film_grain_params.point_cb_value[i - 1]) + ")");
return PARSER_INVALID_ARG;
}
p_frame_header->film_grain_params.point_cb_scaling[i] = Parser::ReadBits(p_stream, offset, 8);
}
p_frame_header->film_grain_params.num_cr_points = Parser::ReadBits(p_stream, offset, 4);
CHECK_ALLOWED_MAX("num_cr_points", p_frame_header->film_grain_params.num_cr_points, 10);
if (p_seq_header->color_config.subsampling_x == 1 && p_seq_header->color_config.subsampling_y == 1) {
if (p_frame_header->film_grain_params.num_cb_points == 0 && p_frame_header->film_grain_params.num_cr_points != 0) {
ERR("If subsampling_x is equal to 1 and subsampling_y is equal to 1 and num_cb_points is equal to 0, it is a requirement of bitstream conformance that num_cr_points is equal to 0.");
return PARSER_WRONG_STATE;
}
if (p_frame_header->film_grain_params.num_cb_points != 0 && p_frame_header->film_grain_params.num_cr_points == 0) {
ERR("If subsampling_x is equal to 1 and subsampling_y is equal to 1 and num_cb_points is not equal to 0, it is a requirement of bitstream conformance that num_cr_points is not equal to 0.");
return PARSER_WRONG_STATE;
}
}
for ( i = 0; i < p_frame_header->film_grain_params.num_cr_points; i++ )
{
p_frame_header->film_grain_params.point_cr_value[i] = Parser::ReadBits(p_stream, offset, 8);
if (i > 0 && p_frame_header->film_grain_params.point_cr_value[i] <= p_frame_header->film_grain_params.point_cr_value[i - 1]) {
ERR("point_cr_value["+ TOSTR(i) + "] (" + TOSTR(p_frame_header->film_grain_params.point_cr_value[i]) + ") should be greater than point_cr_value[" + TOSTR(i - 1) + "] (" + TOSTR(p_frame_header->film_grain_params.point_cr_value[i - 1]) + ")");
return PARSER_INVALID_ARG;
}
p_frame_header->film_grain_params.point_cr_scaling[i] = Parser::ReadBits(p_stream, offset, 8);
}
}
@@ -2440,6 +2533,7 @@ void Av1VideoParser::FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av
p_frame_header->film_grain_params.overlap_flag = Parser::GetBit(p_stream, offset);
p_frame_header->film_grain_params.clip_to_restricted_range = Parser::GetBit(p_stream, offset);
return PARSER_OK;
}
#if DBGINFO
+8 -8
View File
@@ -203,9 +203,9 @@ protected:
/*! \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
* \return <tt>ParserResult</tt>
*/
void ParseSequenceHeaderObu(uint8_t *p_stream, size_t size);
ParserResult 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
@@ -252,9 +252,9 @@ protected:
* \param [out] offset Updated bit offset
* \param [in] p_seq_header Pointer to sequence header struct
* \param [out] p_frame_header Pointer to frame header struct
* \return None
* \return <tt>ParserResult</tt>
*/
void FrameSize(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
ParserResult FrameSize(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
/*! \brief Function to parse super res parameters
* \param [in] p_stream Pointer to the bit stream
@@ -350,9 +350,9 @@ protected:
* \param [out] offset Updated bit offset
* \param [in] p_seq_header Pointer to sequence header struct
* \param [out] p_frame_header Pointer to frame header struct
* \return None
* \return <tt>ParserResult</tt>
*/
void TileInfo(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
ParserResult TileInfo(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
/*! \brief Function to calculate the smallest value for k such that blk_size << k is greater than or equal to target.
* \param [in] blk_size Block size
@@ -522,9 +522,9 @@ protected:
* \param [out] offset Updated bit offset
* \param [in] p_seq_header Pointer to sequence header struct
* \param [out] p_frame_header Pointer to frame header struct
* \return None
* \return <tt>ParserResult</tt>
*/
void FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
ParserResult FilmGrainParams(const uint8_t *p_stream, size_t &offset, Av1SequenceHeader *p_seq_header, Av1FrameHeader *p_frame_header);
/*! \brief Function to round a number to 2^n
* \param [in] x The number to be rounded