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;
           }