Error resilience: Added a few error handling measures. (#581)

* * Error resilience: Added a few error handling measures.
 - AV1: Added check flags to sequence header and frame header to indicate if the headers are parsed without errors. The flags are used to check if the parsing process which refers to the headers can proceed or stop.
 - AV1: Added divide by 0 check on tile columns in tile group parsing.
 - AV1: Added invalid OBU size check in AV1 elementary stream parsing in bitstream reader.
 - All codecs: Added divide by 0 check in display aspect ratio calculation.

* * Error resilience: Fixed a typo in an error message.
This commit is contained in:
jeffqjiangNew
2025-05-06 12:02:51 -04:00
committed by GitHub
parent 41338c40f3
commit a861d6f1d2
6 changed files with 40 additions and 9 deletions
+5 -1
View File
@@ -859,7 +859,7 @@ uint32_t RocVideoESParser::ReadUVLC(const uint8_t *p_stream, size_t &bit_offset)
int RocVideoESParser::CheckAv1EStream(uint8_t *p_stream, int stream_size) {
int score = 0;
uint8_t *obu_stream = p_stream;
int curr_offset = 0;
uint32_t curr_offset = 0;
int temporal_delimiter_obu_present = 0;
int seq_header_obu_present = 0;
int frame_header_obu_present = 0;
@@ -1080,6 +1080,10 @@ int RocVideoESParser::CheckAv1EStream(uint8_t *p_stream, int stream_size) {
break;
}
// Check before update
if (obu_size > (stream_size - curr_offset)) {
break;
}
curr_offset += obu_size;
}
if (syntax_error) {
+2
View File
@@ -185,6 +185,7 @@ typedef struct {
} Av1ColorConfig;
typedef struct {
uint32_t is_received;
uint32_t seq_profile;
uint32_t still_picture;
uint32_t reduced_still_picture_header;
@@ -403,6 +404,7 @@ typedef struct {
} Av1FilmGrainParams;
typedef struct {
uint32_t is_received;
uint32_t show_existing_frame;
uint32_t frame_to_show_map_idx;
Av1TemporalPointInfo temporal_point_info;
+21 -2
View File
@@ -232,8 +232,10 @@ ParserResult Av1VideoParser::NotifyNewSequence(Av1SequenceHeader *p_seq_header,
int disp_width = (video_format_params_.display_area.right - video_format_params_.display_area.left);
int disp_height = (video_format_params_.display_area.bottom - video_format_params_.display_area.top);
int gcd = std::__gcd(disp_width, disp_height); // greatest common divisor
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
if (gcd) {
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
}
video_format_params_.reconfig_options = ROCDEC_RECONFIG_NEW_SURFACES;
video_format_params_.video_signal_description = {0};
@@ -898,6 +900,7 @@ void Av1VideoParser::ParseSequenceHeaderObu(uint8_t *p_stream, size_t size) {
if (p_seq_header->film_grain_params_present) {
CheckAndAdjustDecBufPoolSize(BUFFER_POOL_MAX_SIZE * 2);
}
p_seq_header->is_received = 1;
}
ParserResult Av1VideoParser::ParseFrameHeaderObu(uint8_t *p_stream, size_t size, int *p_bytes_parsed) {
@@ -930,6 +933,12 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
uint32_t all_frames = (1 << NUM_REF_FRAMES) - 1;
int i;
p_frame_header->is_received = 0;
if (p_seq_header->is_received == 0) {
ERR("No valid sequence header received before frame header.");
return PARSER_WRONG_STATE;
}
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;
}
@@ -1232,6 +1241,7 @@ ParserResult Av1VideoParser::ParseUncompressedHeader(uint8_t *p_stream, size_t s
FilmGrainParams(p_stream, offset, p_seq_header, p_frame_header);
*p_bytes_parsed = (offset + 7) >> 3;
p_frame_header->is_received = 1;
return PARSER_OK;
}
@@ -1246,6 +1256,11 @@ ParserResult Av1VideoParser::ParseTileGroupObu(uint8_t *p_stream, size_t size) {
uint8_t *p_tg_buf = p_stream;
uint32_t tg_size = size;
if (p_frame_header->is_received == 0) {
ERR("No valid frame header received before tile group.");
return PARSER_WRONG_STATE;
}
if (p_tile_group->tile_group_num == 0) {
p_tile_group->buffer_ptr = p_stream;
}
@@ -1268,6 +1283,10 @@ ParserResult Av1VideoParser::ParseTileGroupObu(uint8_t *p_stream, size_t size) {
p_tg_buf += header_bytes;
tg_size -= header_bytes;
for (int tile_num = p_tile_group->tg_start; tile_num <= p_tile_group->tg_end; tile_num++) {
if (tile_cols == 0) {
ERR("Tile columns is 0.");
return PARSER_WRONG_STATE;
}
p_tile_group->tile_data_info[tile_num].tile_row = tile_num / tile_cols;
p_tile_group->tile_data_info[tile_num].tile_col = tile_num % tile_cols;
int last_tile = (tile_num == p_tile_group->tg_end);
+4 -2
View File
@@ -392,8 +392,10 @@ ParserResult AvcVideoParser::NotifyNewSps(AvcSeqParameterSet *p_sps) {
int disp_width = (video_format_params_.display_area.right - video_format_params_.display_area.left) * sar.numerator;
int disp_height = (video_format_params_.display_area.bottom - video_format_params_.display_area.top) * sar.denominator;
int gcd = std::__gcd(disp_width, disp_height); // greatest common divisor
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
if (gcd) {
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
}
video_format_params_.reconfig_options = ROCDEC_RECONFIG_NEW_SURFACES;
if (p_sps->vui_parameters_present_flag) {
+4 -2
View File
@@ -188,8 +188,10 @@ int HevcVideoParser::FillSeqCallbackFn(HevcSeqParamSet* sps_data) {
int disp_width = (video_format_params_.display_area.right - video_format_params_.display_area.left) * sar.numerator;
int disp_height = (video_format_params_.display_area.bottom - video_format_params_.display_area.top) * sar.denominator;
int gcd = std::__gcd(disp_width, disp_height); // greatest common divisor
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
if (gcd) {
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
}
video_format_params_.reconfig_options = ROCDEC_RECONFIG_NEW_SURFACES;
if (sps_data->vui_parameters_present_flag) {
+4 -2
View File
@@ -226,8 +226,10 @@ ParserResult Vp9VideoParser::NotifyNewSequence(Vp9UncompressedHeader *p_uncomp_h
int disp_width = (video_format_params_.display_area.right - video_format_params_.display_area.left);
int disp_height = (video_format_params_.display_area.bottom - video_format_params_.display_area.top);
int gcd = std::__gcd(disp_width, disp_height); // greatest common divisor
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
if (gcd) {
video_format_params_.display_aspect_ratio.x = disp_width / gcd;
video_format_params_.display_aspect_ratio.y = disp_height / gcd;
}
video_format_params_.reconfig_options = reconfig_option_;
video_format_params_.video_signal_description = {0};