Check if all tile groups are received in order.
Check the following bitstream conformance requirement in Section 6.10.1
of the AV1 spec:
It is a requirement of bitstream conformance that the value of
tg_start is equal to the value of TileNum at the point that
tile_group_obu is invoked.
This requirement means the tile numbers between consecutive tile groups
of a frame should be contiguous, i.e., monotonically increasing with no
gaps.
BUG=oss-fuzz:15363
Change-Id: I99cc40f8aebd55ff1051cf66dff1db88f801883b
diff --git a/av1/decoder/decoder.h b/av1/decoder/decoder.h
index 58fc9db..b70630f 100644
--- a/av1/decoder/decoder.h
+++ b/av1/decoder/decoder.h
@@ -218,6 +218,8 @@
int operating_point;
int current_operating_point;
int seen_frame_header;
+ // The expected start_tile (tg_start syntax element) of the next tile group.
+ int next_start_tile;
// State if the camera frame header is already decoded while
// large_scale_tile = 1.
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index e41fed4..40171cf 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -300,6 +300,12 @@
*start_tile = aom_rb_read_literal(rb, tile_bits);
*end_tile = aom_rb_read_literal(rb, tile_bits);
}
+ if (*start_tile != pbi->next_start_tile) {
+ aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME,
+ "tg_start (%d) must be equal to %d", *start_tile,
+ pbi->next_start_tile);
+ return -1;
+ }
if (*start_tile > *end_tile) {
aom_internal_error(
&cm->error, AOM_CODEC_CORRUPT_FRAME,
@@ -313,6 +319,7 @@
num_tiles);
return -1;
}
+ pbi->next_start_tile = (*end_tile == num_tiles - 1) ? 0 : *end_tile + 1;
return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
}
@@ -339,7 +346,6 @@
tg_payload_size = (uint32_t)(*p_data_end - data);
- // TODO(shan): For now, assume all tile groups received in order
*is_last_tg = end_tile == cm->tile_rows * cm->tile_cols - 1;
return header_size + tg_payload_size;
}
@@ -748,6 +754,7 @@
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
pbi->seen_frame_header = 0;
+ pbi->next_start_tile = 0;
if (data_end < data) {
cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
@@ -813,6 +820,7 @@
case OBU_TEMPORAL_DELIMITER:
decoded_payload_size = read_temporal_delimiter_obu();
pbi->seen_frame_header = 0;
+ pbi->next_start_tile = 0;
break;
case OBU_SEQUENCE_HEADER:
decoded_payload_size = read_sequence_header_obu(pbi, &rb);