[NORMATIVE] ext_tile: write/read tile information

This patch started to handle the tile information writing and reading
in large scale tile coding mode. The purpose is to remove normative
changes in the uncompressed frame header regarding ext_tile.

More patch will follow.

BUG=aomedia:1938

Change-Id: Ic43c5fe74ca83c7069b482ff1fb5d51fd9b8beb5
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index e706277..068530d 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -2012,46 +2012,6 @@
 static void read_tile_info(AV1Decoder *const pbi,
                            struct aom_read_bit_buffer *const rb) {
   AV1_COMMON *const cm = &pbi->common;
-#if EXT_TILE_DEBUG
-  if (cm->large_scale_tile) {
-    // Read the tile width/height
-    if (cm->seq_params.sb_size == BLOCK_128X128) {
-      cm->tile_width = aom_rb_read_literal(rb, 5) + 1;
-      cm->tile_height = aom_rb_read_literal(rb, 5) + 1;
-    } else {
-      cm->tile_width = aom_rb_read_literal(rb, 6) + 1;
-      cm->tile_height = aom_rb_read_literal(rb, 6) + 1;
-    }
-
-    cm->tile_width <<= cm->seq_params.mib_size_log2;
-    cm->tile_height <<= cm->seq_params.mib_size_log2;
-
-    cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
-    cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
-
-    // Get the number of tiles
-    cm->tile_cols = 1;
-    while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
-
-    cm->tile_rows = 1;
-    while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
-
-    if (cm->tile_cols * cm->tile_rows > 1) {
-      // Read the number of bytes used to store tile size
-      pbi->tile_col_size_bytes = aom_rb_read_literal(rb, 2) + 1;
-      pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1;
-    }
-    for (int i = 0; i <= cm->tile_cols; i++) {
-      cm->tile_col_start_sb[i] =
-          ((i * cm->tile_width - 1) >> cm->seq_params.mib_size_log2) + 1;
-    }
-    for (int i = 0; i <= cm->tile_rows; i++) {
-      cm->tile_row_start_sb[i] =
-          ((i * cm->tile_height - 1) >> cm->seq_params.mib_size_log2) + 1;
-    }
-    return;
-  }
-#endif  // EXT_TILE_DEBUG
 
   read_tile_info_max_tile(cm, rb);
 
@@ -2065,6 +2025,55 @@
   }
 }
 
+#if EXT_TILE_DEBUG
+static void read_ext_tile_info(AV1Decoder *const pbi,
+                               struct aom_read_bit_buffer *const rb) {
+  AV1_COMMON *const cm = &pbi->common;
+
+  // Read the tile width/height
+  if (cm->seq_params.sb_size == BLOCK_128X128) {
+    cm->tile_width = aom_rb_read_literal(rb, 5) + 1;
+    cm->tile_height = aom_rb_read_literal(rb, 5) + 1;
+  } else {
+    cm->tile_width = aom_rb_read_literal(rb, 6) + 1;
+    cm->tile_height = aom_rb_read_literal(rb, 6) + 1;
+  }
+
+  cm->tile_width <<= cm->seq_params.mib_size_log2;
+  cm->tile_height <<= cm->seq_params.mib_size_log2;
+
+  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
+  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
+
+  // Get the number of tiles
+  cm->tile_cols = 1;
+  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
+
+  cm->tile_rows = 1;
+  while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
+
+  if (cm->tile_cols * cm->tile_rows > 1) {
+    // Read the number of bytes used to store tile size
+    pbi->tile_col_size_bytes = aom_rb_read_literal(rb, 2) + 1;
+    pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1;
+  }
+  for (int i = 0; i <= cm->tile_cols; i++) {
+    cm->tile_col_start_sb[i] =
+        ((i * cm->tile_width - 1) >> cm->seq_params.mib_size_log2) + 1;
+  }
+  for (int i = 0; i <= cm->tile_rows; i++) {
+    cm->tile_row_start_sb[i] =
+        ((i * cm->tile_height - 1) >> cm->seq_params.mib_size_log2) + 1;
+  }
+
+  // This is only needed to be compatible with max_tile.
+  cm->log2_tile_cols = 0;
+  while (cm->tile_cols > (1 << cm->log2_tile_cols)) ++cm->log2_tile_cols;
+  cm->log2_tile_rows = 0;
+  while (cm->tile_rows > (1 << cm->log2_tile_rows)) ++cm->log2_tile_rows;
+}
+#endif  // EXT_TILE_DEBUG
+
 static size_t mem_get_varsize(const uint8_t *src, int sz) {
   switch (sz) {
     case 1: return src[0];
@@ -3891,6 +3900,9 @@
   cm->cur_frame->film_grain_params_present = cm->film_grain_params_present;
   read_film_grain(cm, rb);
 
+#if EXT_TILE_DEBUG
+  if (cm->large_scale_tile) read_ext_tile_info(pbi, rb);
+#endif  // EXT_TILE_DEBUG
   set_single_tile_decoding_mode(&pbi->common);
   return 0;
 }
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 037d7b6..ebec2d3 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2193,45 +2193,9 @@
 static void write_tile_info(const AV1_COMMON *const cm,
                             struct aom_write_bit_buffer *saved_wb,
                             struct aom_write_bit_buffer *wb) {
-  if (cm->large_scale_tile) {
-    const int tile_width =
-        ALIGN_POWER_OF_TWO(cm->tile_width, cm->seq_params.mib_size_log2) >>
-        cm->seq_params.mib_size_log2;
-    const int tile_height =
-        ALIGN_POWER_OF_TWO(cm->tile_height, cm->seq_params.mib_size_log2) >>
-        cm->seq_params.mib_size_log2;
-
-    assert(tile_width > 0);
-    assert(tile_height > 0);
-
-    // Write the tile sizes
-    if (cm->seq_params.sb_size == BLOCK_128X128) {
-      assert(tile_width <= 32);
-      assert(tile_height <= 32);
-      aom_wb_write_literal(wb, tile_width - 1, 5);
-      aom_wb_write_literal(wb, tile_height - 1, 5);
-    } else {
-      assert(tile_width <= 64);
-      assert(tile_height <= 64);
-      aom_wb_write_literal(wb, tile_width - 1, 6);
-      aom_wb_write_literal(wb, tile_height - 1, 6);
-    }
-  } else {
-    write_tile_info_max_tile(cm, wb);
-  }
+  write_tile_info_max_tile(cm, wb);
 
   *saved_wb = *wb;
-  if (cm->large_scale_tile) {
-    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);
-    }
-    return;
-  }
   if (cm->tile_rows * cm->tile_cols > 1) {
     // tile id used for cdf update
     aom_wb_write_literal(wb, 0, cm->log2_tile_cols + cm->log2_tile_rows);
@@ -2240,6 +2204,43 @@
   }
 }
 
+static void write_ext_tile_info(const AV1_COMMON *const cm,
+                                struct aom_write_bit_buffer *saved_wb,
+                                struct aom_write_bit_buffer *wb) {
+  const int tile_width =
+      ALIGN_POWER_OF_TWO(cm->tile_width, cm->seq_params.mib_size_log2) >>
+      cm->seq_params.mib_size_log2;
+  const int tile_height =
+      ALIGN_POWER_OF_TWO(cm->tile_height, cm->seq_params.mib_size_log2) >>
+      cm->seq_params.mib_size_log2;
+
+  assert(tile_width > 0);
+  assert(tile_height > 0);
+
+  // Write the tile sizes
+  if (cm->seq_params.sb_size == BLOCK_128X128) {
+    assert(tile_width <= 32);
+    assert(tile_height <= 32);
+    aom_wb_write_literal(wb, tile_width - 1, 5);
+    aom_wb_write_literal(wb, tile_height - 1, 5);
+  } else {
+    assert(tile_width <= 64);
+    assert(tile_height <= 64);
+    aom_wb_write_literal(wb, tile_width - 1, 6);
+    aom_wb_write_literal(wb, tile_height - 1, 6);
+  }
+
+  *saved_wb = *wb;
+  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);
+  }
+}
+
 #if USE_GF16_MULTI_LAYER
 static int get_refresh_mask_gf16(AV1_COMP *cpi) {
   if (cpi->common.frame_type == KEY_FRAME || frame_is_sframe(&cpi->common))
@@ -3320,6 +3321,8 @@
     if (flip_back_update_parameters_flag)
       cm->film_grain_params.update_parameters = 0;
   }
+
+  if (cm->large_scale_tile) write_ext_tile_info(cm, saved_wb, wb);
 }
 
 static int choose_size_bytes(uint32_t size, int spare_msbs) {
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index bb2767d..c5f5a39 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -866,6 +866,13 @@
       cm->tile_row_start_sb[i] =
           ((i * cm->tile_height - 1) >> cm->seq_params.mib_size_log2) + 1;
     }
+
+    // (Yunqing) This is needed to be compatible with max_tile. Otherwise, the
+    // decoder would crash.
+    cm->log2_tile_cols = 0;
+    while (cm->tile_cols > (1 << cm->log2_tile_cols)) ++cm->log2_tile_cols;
+    cm->log2_tile_rows = 0;
+    while (cm->tile_rows > (1 << cm->log2_tile_rows)) ++cm->log2_tile_rows;
   } else {
     set_tile_info_max_tile(cpi);
   }