Handle failure of read_one_tile_group_obu(). On failure, read_one_tile_group_obu() sets cm->error.error_code and returns 0. Since the caller (aom_decode_frame_from_obus) does not save the return value in a local variable, detect failure by checking cm->error.error_code. read_tile_group_header() should return failure if start_tile > end_tile, required by Section 6.10.1 of the spec: "It is a requirement of bitstream conformance that the value of tg_end is greater than or equal to tg_start." Document the failure behavior of read_tile_group_header(), read_one_tile_group_obu(), read_and_decode_one_tile_list(), and read_metadata(). BUG=aomedia:2185 Change-Id: I534e5eab04d738fdffc5d31b360a6f04061e23a1
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c index c5c9376..28e3d57 100644 --- a/av1/decoder/obu.c +++ b/av1/decoder/obu.c
@@ -292,6 +292,8 @@ trailing_bits_present); } +// On success, returns the tile group header size. On failure, calls +// aom_internal_error() and returns -1. static int32_t read_tile_group_header(AV1Decoder *pbi, struct aom_read_bit_buffer *rb, int *start_tile, int *end_tile, @@ -303,26 +305,33 @@ if (!pbi->common.large_scale_tile && num_tiles > 1) { tile_start_and_end_present_flag = aom_rb_read_bit(rb); + if (tile_start_implicit && tile_start_and_end_present_flag) { + aom_internal_error( + &cm->error, AOM_CODEC_UNSUP_BITSTREAM, + "For OBU_FRAME type obu tile_start_and_end_present_flag must be 0"); + return -1; + } } if (pbi->common.large_scale_tile || num_tiles == 1 || !tile_start_and_end_present_flag) { *start_tile = 0; *end_tile = num_tiles - 1; - return ((rb->bit_offset - saved_bit_offset + 7) >> 3); + } else { + int tile_bits = cm->log2_tile_rows + cm->log2_tile_cols; + *start_tile = aom_rb_read_literal(rb, tile_bits); + *end_tile = aom_rb_read_literal(rb, tile_bits); } - if (tile_start_implicit && tile_start_and_end_present_flag) { - aom_internal_error( - &cm->error, AOM_CODEC_UNSUP_BITSTREAM, - "For OBU_FRAME type obu tile_start_and_end_present_flag must be 0"); + if (*start_tile > *end_tile) { + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "tg_end must be greater than or equal to tg_start"); return -1; } - *start_tile = - aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols); - *end_tile = aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols); return ((rb->bit_offset - saved_bit_offset + 7) >> 3); } +// On success, returns the tile group OBU size. On failure, sets +// pbi->common.error.error_code and returns 0. static uint32_t read_one_tile_group_obu( AV1Decoder *pbi, struct aom_read_bit_buffer *rb, int is_first_tg, const uint8_t *data, const uint8_t *data_end, const uint8_t **p_data_end, @@ -337,7 +346,6 @@ header_size = read_tile_group_header(pbi, rb, &start_tile, &end_tile, tile_start_implicit); if (header_size == -1 || byte_alignment(cm, rb)) return 0; - if (start_tile > end_tile) return header_size; data += header_size; av1_decode_tg_tiles_and_wrapup(pbi, data, data_end, p_data_end, start_tile, end_tile, is_first_tg); @@ -431,6 +439,9 @@ } // Only called while large_scale_tile = 1. +// +// On success, returns the tile list OBU size. On failure, sets +// pbi->common.error.error_code and returns 0. static uint32_t read_and_decode_one_tile_list(AV1Decoder *pbi, struct aom_read_bit_buffer *rb, const uint8_t *data, @@ -613,6 +624,7 @@ } } +// Not fully implemented. Always succeeds and returns sz. static size_t read_metadata(const uint8_t *data, size_t sz) { size_t type_length; uint64_t type_value; @@ -785,6 +797,7 @@ pbi, &rb, is_first_tg_obu_received, data + obu_payload_offset, data + payload_size, p_data_end, &frame_decoding_finished, obu_header.type == OBU_FRAME); + if (cm->error.error_code != AOM_CODEC_OK) return -1; is_first_tg_obu_received = 0; if (frame_decoding_finished) pbi->seen_frame_header = 0; break;