Implement the frame_header_copy check in the spec.
Section 5.9.1 of the spec says:
frame_header_obu( ) {
if ( SeenFrameHeader == 1 ) {
frame_header_copy()
} else {
SeenFrameHeader = 1
uncompressed_header( )
if ( show_existing_frame ) {
decode_frame_wrapup( )
SeenFrameHeader = 0
} else {
TileNum = 0
SeenFrameHeader = 1
}
}
}
Note that if SeenFrameHeader is equal to 1, we should call
frame_header_copy().
Section 6.8.1 of the spec says:
frame_header_copy is a function call that indicates that a copy of the
previous frame_header_obu should be inserted at this point.
Note: Bitstreams may contain several copies of the frame_header_obu
interspersed with tile_group_obu to allow for greater error
resilience. However, the copies must contain identical contents to
the original frame_header_obu.
Change-Id: I342716452d64be36989b445804024a4899c7e6df
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index 3619264..ad7a955 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -751,6 +751,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));
@@ -852,14 +862,15 @@
(cm->large_scale_tile && !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->large_scale_tile)
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;
}