[NORMATIVE][obu] Add obu_redundant_frame_header.

Use a different OBU type when inserting redundant Frame Header
OBUs. This patch introduces the OBU type
OBU_REDUNDANT_FRAME_HEADER, which is used as the OBU type
when a duplicated frame header is inserted into the bitstream.

BUG=aomedia:1584

Change-Id: I8dfaa9893221d3155bd298f6d6d09182f47f6862
diff --git a/aom/aom_codec.h b/aom/aom_codec.h
index 7838008..9cca2b3 100644
--- a/aom/aom_codec.h
+++ b/aom/aom_codec.h
@@ -489,6 +489,7 @@
   OBU_TILE_GROUP = 4,
   OBU_METADATA = 5,
   OBU_FRAME = 6,
+  OBU_REDUNDANT_FRAME_HEADER = 7,
   OBU_PADDING = 15,
 } OBU_TYPE;
 
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index ed188e2..8f3a08e 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -56,6 +56,12 @@
     case OBU_SEQUENCE_HEADER:
     case OBU_TEMPORAL_DELIMITER:
     case OBU_FRAME_HEADER:
+#if CONFIG_OBU_REDUNDANT_FRAME_HEADER
+    case OBU_REDUNDANT_FRAME_HEADER:
+#endif  // CONFIG_OBU_REDUNDANT_FRAME_HEADER
+#if CONFIG_OBU_FRAME
+    case OBU_FRAME:
+#endif  // CONFIG_OBU_FRAME
     case OBU_TILE_GROUP:
     case OBU_METADATA:
     case OBU_PADDING: break;
@@ -71,8 +77,13 @@
     case OBU_SEQUENCE_HEADER:
     case OBU_TEMPORAL_DELIMITER:
     case OBU_FRAME_HEADER:
-    case OBU_TILE_GROUP:
+#if CONFIG_OBU_REDUNDANT_FRAME_HEADER
+    case OBU_REDUNDANT_FRAME_HEADER:
+#endif  // CONFIG_OBU_REDUNDANT_FRAME_HEADER
+#if CONFIG_OBU_FRAME
     case OBU_FRAME:
+#endif  // CONFIG_OBU_FRAME
+    case OBU_TILE_GROUP:
     case OBU_METADATA:
     case OBU_PADDING: valid_type = 1; break;
     default: break;
@@ -423,6 +434,9 @@
 #if CONFIG_OBU_FRAME
       case OBU_FRAME:
 #endif  // CONFIG_OBU_FRAME
+#if CONFIG_OBU_REDUNDANT_FRAME_HEADER
+      case OBU_REDUNDANT_FRAME_HEADER:
+#endif  // CONFIG_OBU_REDUNDANT_FRAME_HEADER
       case OBU_FRAME_HEADER:
         // Only decode first frame header received
         if (!frame_header_received) {
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 716ad7b..b5f40df 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3506,8 +3506,7 @@
   struct aom_write_bit_buffer wb = { dst, 0 };
   uint32_t size = 0;
 
-  // first bit is obu_forbidden_bit according to R19
-  aom_wb_write_literal(&wb, 0, 1);
+  aom_wb_write_literal(&wb, 0, 1);  // forbidden bit.
   aom_wb_write_literal(&wb, (int)obu_type, 4);
 #if CONFIG_OBU_SIZE_AFTER_HEADER
   aom_wb_write_literal(&wb, obu_extension ? 1 : 0, 1);
@@ -3654,6 +3653,7 @@
 
 typedef struct {
   uint8_t *frame_header;
+  size_t obu_header_byte_offset;
   size_t total_length;
 } FrameHeaderInfo;
 
@@ -3953,6 +3953,14 @@
 
           // Insert a copy of the Frame Header OBU.
           memcpy(data, fh_info->frame_header, fh_info->total_length);
+
+#if CONFIG_OBU_REDUNDANT_FRAME_HEADER
+          // Rewrite the OBU header to change the OBU type to Redundant Frame
+          // Header.
+          write_obu_header(OBU_REDUNDANT_FRAME_HEADER, obu_extension_header,
+                           &data[fh_info->obu_header_byte_offset]);
+#endif  // CONFIG_OBU_REDUNDANT_FRAME_HEADER
+
           data += fh_info->total_length;
 
           curr_tg_data_size += fh_info->total_length;
@@ -3975,7 +3983,7 @@
   AV1_COMMON *const cm = &cpi->common;
   uint32_t obu_header_size = 0;
   uint32_t obu_payload_size = 0;
-  FrameHeaderInfo fh_info = { NULL, 0 };
+  FrameHeaderInfo fh_info = { NULL, 0, 0 };
 #if CONFIG_SCALABILITY
   const uint8_t enhancement_layers_cnt = cm->enhancement_layers_cnt;
   const uint8_t obu_extension_header =
@@ -4042,9 +4050,18 @@
     }
 #else
     const size_t length_field_size = PRE_OBU_SIZE_BYTES;
+    fh_info.obu_header_byte_offset = length_field_size;
     mem_put_le32(data, obu_header_size + obu_payload_size);
 #endif  // CONFIG_OBU_SIZING
 
+#if CONFIG_OBU_REDUNDANT_FRAME_HEADER
+#if CONFIG_OBU_SIZE_AFTER_HEADER
+    fh_info.obu_header_byte_offset = 0;
+#else
+    fh_info.obu_header_byte_offset = length_field_size;
+#endif  // CONFIG_OBU_SIZE_AFTER_HEADER
+#endif  // CONFIG_OBU_REDUNDANT_FRAME_HEADER
+
     fh_info.total_length =
         obu_header_size + obu_payload_size + length_field_size;
     data += fh_info.total_length;
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index abbf800..edec991 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -114,6 +114,7 @@
 set(CONFIG_NO_FRAME_CONTEXT_SIGNALING 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_OBU_FRAME 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_OBU_NO_IVF 0 CACHE NUMBER "AV1 experiment flag.")
+set(CONFIG_OBU_REDUNDANT_FRAME_HEADER 0 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_OBU_SIZE_AFTER_HEADER 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_OBU_SIZING 1 CACHE NUMBER "AV1 experiment flag.")
 set(CONFIG_RD_DEBUG 0 CACHE NUMBER "AV1 experiment flag.")