Make ext-tile and obu work togather

This commit resolves the broken coding pipeline in ext-tile when
obu is enabled. It fixes the unit test failure due to enc/dec
mismatch.

BUG=aomedia:1143

Change-Id: I7f083c90959939048f59540f4427dc94c709a315
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index ef7b5a6..fcbbd90 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3647,6 +3647,14 @@
   AV1_COMMON *const cm = &pbi->common;
   uint32_t saved_bit_offset = rb->bit_offset;
 
+#if CONFIG_EXT_TILE
+  if (pbi->common.large_scale_tile) {
+    *startTile = 0;
+    *endTile = pbi->common.tile_rows * pbi->common.tile_cols - 1;
+    return ((rb->bit_offset - saved_bit_offset + 7) >> 3);
+  }
+#endif
+
   *startTile = aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols);
   *endTile = aom_rb_read_literal(rb, cm->log2_tile_rows + cm->log2_tile_cols);
 
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 50ded9f..f49df8d 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -81,6 +81,9 @@
 #endif  // CONFIG_LOOP_RESTORATION
 #if CONFIG_OBU
 static void write_uncompressed_header_obu(AV1_COMP *cpi,
+#if CONFIG_EXT_TILE
+                                          struct aom_write_bit_buffer *saved_wb,
+#endif
                                           struct aom_write_bit_buffer *wb);
 #else
 static void write_uncompressed_header_frame(AV1_COMP *cpi,
@@ -2922,7 +2925,7 @@
 }
 #endif  // CONFIG_EXT_TILE
 
-#if !CONFIG_OBU || CONFIG_EXT_TILE
+#if !CONFIG_OBU
 static uint32_t write_tiles(AV1_COMP *const cpi, uint8_t *const dst,
                             unsigned int *max_tile_size,
                             unsigned int *max_tile_col_size) {
@@ -3883,6 +3886,9 @@
 #else
 // New function based on HLS R18
 static void write_uncompressed_header_obu(AV1_COMP *cpi,
+#if CONFIG_EXT_TILE
+                                          struct aom_write_bit_buffer *saved_wb,
+#endif
                                           struct aom_write_bit_buffer *wb) {
   AV1_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
@@ -4149,7 +4155,14 @@
   }
 #endif  // CONFIG_REFERENCE_BUFFER
 
-  if (!cm->error_resilient_mode) {
+#if CONFIG_EXT_TILE
+  const int might_bwd_adapt =
+      !(cm->error_resilient_mode || cm->large_scale_tile);
+#else
+  const int might_bwd_adapt = !cm->error_resilient_mode;
+#endif  // CONFIG_EXT_TILE
+
+  if (might_bwd_adapt) {
     aom_wb_write_bit(
         wb, cm->refresh_frame_context == REFRESH_FRAME_CONTEXT_FORWARD);
   }
@@ -4234,7 +4247,21 @@
 
 #if !CONFIG_TILE_INFO_FIRST
   write_tile_info(cm, wb);
+
+#if CONFIG_EXT_TILE
+  *saved_wb = *wb;
+  // Write tile size magnitudes
+  if (cm->tile_rows * cm->tile_cols > 1) {
+    // Note that the last item in the uncompressed header is the data
+    // describing tile configuration.
+    // Number of bytes in tile column size - 1
+    aom_wb_write_literal(wb, 0, 2);
+
+    // Number of bytes in tile size - 1
+    aom_wb_write_literal(wb, 0, 2);
+  }
 #endif
+#endif  // !CONFIG_TILE_INFO_FIRST
 }
 #endif  // CONFIG_OBU
 
@@ -4440,13 +4467,21 @@
   return size;
 }
 
-static uint32_t write_frame_header_obu(AV1_COMP *cpi, uint8_t *const dst) {
+static uint32_t write_frame_header_obu(AV1_COMP *cpi,
+#if CONFIG_EXT_TILE
+                                       struct aom_write_bit_buffer *saved_wb,
+#endif
+                                       uint8_t *const dst) {
   AV1_COMMON *const cm = &cpi->common;
   struct aom_write_bit_buffer wb = { dst, 0 };
   uint32_t total_size = 0;
   uint32_t compressed_hdr_size, uncompressed_hdr_size;
 
-  write_uncompressed_header_obu(cpi, &wb);
+  write_uncompressed_header_obu(cpi,
+#if CONFIG_EXT_TILE
+                                saved_wb,
+#endif
+                                &wb);
 
   if (cm->show_existing_frame) {
     total_size = aom_wb_bytes_written(&wb);
@@ -4454,8 +4489,11 @@
   }
 
 #if !CONFIG_TILE_INFO_FIRST
-  // write the tile length code  (Always 4 bytes for now)
-  aom_wb_write_literal(&wb, 3, 2);
+// write the tile length code  (Always 4 bytes for now)
+#if CONFIG_EXT_TILE
+  if (!cm->large_scale_tile)
+#endif
+    aom_wb_write_literal(&wb, 3, 2);
 #endif
 
   if (!use_compressed_header(cm)) {
@@ -4493,6 +4531,9 @@
                                        unsigned int *max_tile_col_size,
                                        uint8_t *const frame_header_obu_location,
                                        uint32_t frame_header_obu_size,
+#if CONFIG_EXT_TILE
+                                       struct aom_write_bit_buffer *saved_wb,
+#endif
                                        int insert_frame_header_obu_flag) {
   AV1_COMMON *const cm = &cpi->common;
   aom_writer mode_bc;
@@ -4529,6 +4570,15 @@
 
 #if CONFIG_EXT_TILE
   if (cm->large_scale_tile) {
+    uint32_t compressed_hdr_size = 0;
+
+    uint32_t tg_hdr_size =
+        write_obu_header(OBU_TILE_GROUP, 0, data + PRE_OBU_SIZE_BYTES);
+    data += tg_hdr_size;
+
+    int tile_size_bytes;
+    int tile_col_size_bytes;
+
     for (tile_col = 0; tile_col < tile_cols; tile_col++) {
       TileInfo tile_info;
       const int is_last_col = (tile_col == tile_cols - 1);
@@ -4548,7 +4598,7 @@
         TileDataEnc *this_tile = &cpi->tile_data[tile_idx];
         av1_tile_set_row(&tile_info, cm, tile_row);
 
-        buf->data = dst + total_size;
+        buf->data = dst + total_size + tg_hdr_size;
 
         // Is CONFIG_EXT_TILE = 1, every tile in the row has a header,
         // even for the last one, unless no tiling is used at all.
@@ -4602,13 +4652,36 @@
 
       if (!is_last_col) {
         uint32_t col_size = total_size - col_offset - 4;
-        mem_put_le32(dst + col_offset, col_size);
+        mem_put_le32(dst + col_offset + tg_hdr_size, col_size);
 
         // If it is not final packing, record the maximum tile column size we
         // see, otherwise, check if the tile size is out of the range.
         *max_tile_col_size = AOMMAX(*max_tile_col_size, col_size);
       }
     }
+
+    if (have_tiles) {
+      total_size =
+          remux_tiles(cm, data, total_size, *max_tile_size, *max_tile_col_size,
+                      &tile_size_bytes, &tile_col_size_bytes);
+    }
+
+    // Now fill in the gaps in the uncompressed header.
+    if (have_tiles) {
+      assert(tile_col_size_bytes >= 1 && tile_col_size_bytes <= 4);
+      aom_wb_write_literal(saved_wb, tile_col_size_bytes - 1, 2);
+
+      assert(tile_size_bytes >= 1 && tile_size_bytes <= 4);
+      aom_wb_write_literal(saved_wb, tile_size_bytes - 1, 2);
+    }
+    // TODO(jbb): Figure out what to do if compressed_hdr_size > 16 bits.
+    assert(compressed_hdr_size <= 0xffff);
+    // Fill in the compressed header size (but only if we're using one)
+    if (use_compressed_header(cm)) {
+      aom_wb_write_literal(saved_wb, compressed_hdr_size, 16);
+    }
+
+    total_size += tg_hdr_size;
   } else {
 #endif  // CONFIG_EXT_TILE
 
@@ -4726,27 +4799,15 @@
 void av1_pack_bitstream(AV1_COMP *const cpi, uint8_t *dst, size_t *size) {
   uint8_t *data = dst;
   uint32_t data_size;
-#if CONFIG_EXT_TILE
-  AV1_COMMON *const cm = &cpi->common;
-  uint32_t compressed_hdr_size = 0;
-  uint32_t uncompressed_hdr_size;
-  struct aom_write_bit_buffer saved_wb;
-  struct aom_write_bit_buffer wb = { data, 0 };
-  const int have_tiles = cm->tile_cols * cm->tile_rows > 1;
-  int tile_size_bytes;
-  int tile_col_size_bytes;
-#endif  // CONFIG_EXT_TILE
   unsigned int max_tile_size;
   unsigned int max_tile_col_size;
-#if CONFIG_OBU
-#if !CONFIG_EXT_TILE
   AV1_COMMON *const cm = &cpi->common;
-#endif
+#if CONFIG_OBU
   uint32_t obu_size;
   uint8_t *frame_header_location;
   uint32_t frame_header_size;
 #endif
-
+  (void)cm;
 #if CONFIG_BITSTREAM_DEBUG
   bitstream_queue_reset_write();
 #endif
@@ -4766,11 +4827,19 @@
     data += obu_size + PRE_OBU_SIZE_BYTES;
   }
 
+#if CONFIG_EXT_TILE
+  struct aom_write_bit_buffer saved_wb;
+#endif
+
   // write frame header obu, preceded by 4-byte size
   frame_header_location = data + PRE_OBU_SIZE_BYTES;
   obu_size = write_obu_header(OBU_FRAME_HEADER, 0, frame_header_location);
   frame_header_size =
-      write_frame_header_obu(cpi, data + PRE_OBU_SIZE_BYTES + obu_size);
+      write_frame_header_obu(cpi,
+#if CONFIG_EXT_TILE
+                             &saved_wb,
+#endif
+                             data + PRE_OBU_SIZE_BYTES + obu_size);
   obu_size += frame_header_size;
 #if CONFIG_ADD_4BYTES_OBUSIZE
   mem_put_le32(data, obu_size);
@@ -4782,15 +4851,27 @@
   } else {
     //  Each tile group obu will be preceded by 4-byte size of the tile group
     //  obu
-    data_size = write_tiles_in_tg_obus(
-        cpi, data, &max_tile_size, &max_tile_col_size,
-        frame_header_location - PRE_OBU_SIZE_BYTES,
-        obu_size + PRE_OBU_SIZE_BYTES, 1 /* cm->error_resilient_mode */);
+    data_size =
+        write_tiles_in_tg_obus(cpi, data, &max_tile_size, &max_tile_col_size,
+                               frame_header_location - PRE_OBU_SIZE_BYTES,
+                               obu_size + PRE_OBU_SIZE_BYTES,
+#if CONFIG_EXT_TILE
+                               &saved_wb,
+#endif
+                               1 /* cm->error_resilient_mode */);
   }
 
 #endif
 
-#if CONFIG_EXT_TILE
+#if CONFIG_EXT_TILE && !CONFIG_OBU
+  uint32_t compressed_hdr_size = 0;
+  uint32_t uncompressed_hdr_size;
+  struct aom_write_bit_buffer saved_wb;
+  struct aom_write_bit_buffer wb = { data, 0 };
+  const int have_tiles = cm->tile_cols * cm->tile_rows > 1;
+  int tile_size_bytes;
+  int tile_col_size_bytes;
+
   if (cm->large_scale_tile) {
 #if !CONFIG_OBU
     write_uncompressed_header_frame(cpi, &wb);
@@ -4853,10 +4934,10 @@
 #if !CONFIG_OBU
     data_size = write_tiles(cpi, data, &max_tile_size, &max_tile_col_size);
 #endif
-#if CONFIG_EXT_TILE
+#if CONFIG_EXT_TILE && !CONFIG_OBU
   }
 #endif  // CONFIG_EXT_TILE
-#if CONFIG_EXT_TILE
+#if CONFIG_EXT_TILE && !CONFIG_OBU
   if (cm->large_scale_tile) {
     if (have_tiles) {
       data_size =
@@ -4883,7 +4964,7 @@
   } else {
 #endif  // CONFIG_EXT_TILE
     data += data_size;
-#if CONFIG_EXT_TILE
+#if CONFIG_EXT_TILE && !CONFIG_OBU
   }
 #endif  // CONFIG_EXT_TILE
   *size = data - dst;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index e2542ad..f481990 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -5288,7 +5288,7 @@
       || (cm->allow_intrabc && NO_FILTER_FOR_IBC)
 #endif  // CONFIG_INTRABC
 #if CONFIG_EXT_TILE
-      || cm->single_tile_decoding
+      || cm->large_scale_tile
 #endif  // CONFIG_EXT_TILE
       ) {
 #if CONFIG_LPF_SB
@@ -5307,7 +5307,7 @@
       || (cm->allow_intrabc && NO_FILTER_FOR_IBC)
 #endif  // CONFIG_INTRABC
 #if CONFIG_EXT_TILE
-      || cm->single_tile_decoding
+      || cm->large_scale_tile
 #endif
       ) {
     no_cdef = 1;