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.

[ROCm/rocdecode commit: a861d6f1d2]
Этот коммит содержится в:
jeffqjiangNew
2025-05-06 12:02:51 -04:00
коммит произвёл GitHub
родитель 798a4a03f0
Коммит 6e1cd70811
6 изменённых файлов: 40 добавлений и 9 удалений
+5 -1
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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
Просмотреть файл
@@ -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};