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.
Cette révision appartient à :
jeffqjiangNew
2025-05-06 12:02:51 -04:00
révisé par GitHub
Parent 41338c40f3
révision a861d6f1d2
6 fichiers modifiés avec 40 ajouts et 9 suppressions
+5 -1
Voir le fichier
@@ -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
Voir le fichier
@@ -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
Voir le fichier
@@ -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
Voir le fichier
@@ -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
Voir le fichier
@@ -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
Voir le fichier
@@ -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};