Implement the frame_header_copy check in the spec.
Reland commit 8b0de61c270ed82ab1162b925bdc896f71c34cf4.
Whenever we receive an OBU_REDUNDANT_FRAME_HEADER, verify that its
contents are identical to the contents of the OBU_FRAME_HEADER of the
current frame.
BUG=aomedia:2814
Change-Id: I01a4fd53bd52309fe34b4557257beaf6a4b2efe6
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index edba708..de24adc 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -848,6 +848,16 @@
AV1_COMMON *const cm = &pbi->common;
int frame_decoding_finished = 0;
int is_first_tg_obu_received = 1;
+ // Whenever pbi->seen_frame_header is set to 1, frame_header is set to the
+ // beginning of the frame_header_obu and frame_header_size is set to its
+ // size. This allows us to check if a redundant frame_header_obu is a copy
+ // of the previous frame_header_obu.
+ //
+ // Initialize frame_header to a dummy nonnull pointer, otherwise the Clang
+ // Static Analyzer in clang 7.0.1 will falsely warn that a null pointer is
+ // passed as an argument to a 'nonnull' parameter of memcmp(). The initial
+ // value will not be used.
+ const uint8_t *frame_header = data;
uint32_t frame_header_size = 0;
ObuHeader obu_header;
memset(&obu_header, 0, sizeof(obu_header));
@@ -953,14 +963,15 @@
(cm->tiles.large_scale && !pbi->camera_frame_header_ready)) {
frame_header_size = read_frame_header_obu(
pbi, &rb, data, p_data_end, obu_header.type != OBU_FRAME);
+ frame_header = data;
pbi->seen_frame_header = 1;
if (!pbi->ext_tile_debug && cm->tiles.large_scale)
pbi->camera_frame_header_ready = 1;
} else {
- // TODO(wtc): Verify that the frame_header_obu is identical to the
- // original frame_header_obu. For now just skip frame_header_size
- // bytes in the bit buffer.
- if (frame_header_size > payload_size) {
+ // Verify that the frame_header_obu is identical to the original
+ // frame_header_obu.
+ if (frame_header_size > payload_size ||
+ memcmp(data, frame_header, frame_header_size) != 0) {
cm->error.error_code = AOM_CODEC_CORRUPT_FRAME;
return -1;
}