Make EXT_TILE compatible with TILE_GROUPS

Added a 1-bit flag 'large_scale_tile'. If it is 0 that is the default value,
use normal tile coding in TILE_GROUPS. If it is 1, use large-scale tile
coding in EXT_TILE.

At large_scale_tile=1 case, if single-tile-decoding is required, then the
loopfilter is disabled.

Related API and unit tests were modified.

Change-Id: I3ba12dc3d80ccf1ab21543ab3b16c02282c34e3b
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index ad0a4a6..600b9ed 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -833,87 +833,103 @@
   int tg_row_start, tg_col_start;
 #endif
 #if CONFIG_EXT_TILE
+  if (cpi->oxcf.large_scale_tile) {
 #if CONFIG_EXT_PARTITION
-  if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
-    cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
-    cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
-    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
-    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
-  } else {
+    if (cpi->oxcf.superblock_size != AOM_SUPERBLOCK_SIZE_64X64) {
+      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 32);
+      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 32);
+      cm->tile_width <<= MAX_MIB_SIZE_LOG2;
+      cm->tile_height <<= MAX_MIB_SIZE_LOG2;
+    } else {
+      cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
+      cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
+      cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
+      cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
+    }
+#else
     cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
     cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
-    cm->tile_width <<= MAX_MIB_SIZE_LOG2 - 1;
-    cm->tile_height <<= MAX_MIB_SIZE_LOG2 - 1;
-  }
-#else
-  cm->tile_width = clamp(cpi->oxcf.tile_columns, 1, 64);
-  cm->tile_height = clamp(cpi->oxcf.tile_rows, 1, 64);
-  cm->tile_width <<= MAX_MIB_SIZE_LOG2;
-  cm->tile_height <<= MAX_MIB_SIZE_LOG2;
+    cm->tile_width <<= MAX_MIB_SIZE_LOG2;
+    cm->tile_height <<= MAX_MIB_SIZE_LOG2;
 #endif  // CONFIG_EXT_PARTITION
 
-  cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
-  cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
+    cm->tile_width = AOMMIN(cm->tile_width, cm->mi_cols);
+    cm->tile_height = AOMMIN(cm->tile_height, cm->mi_rows);
 
-  assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
-  assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
+    assert(cm->tile_width >> MAX_MIB_SIZE <= 32);
+    assert(cm->tile_height >> MAX_MIB_SIZE <= 32);
 
-  // Get the number of tiles
-  cm->tile_cols = 1;
-  while (cm->tile_cols * cm->tile_width < cm->mi_cols) ++cm->tile_cols;
+    // 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;
-#else
-  int min_log2_tile_cols, max_log2_tile_cols;
-  av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
+    cm->tile_rows = 1;
+    while (cm->tile_rows * cm->tile_height < cm->mi_rows) ++cm->tile_rows;
+  } else {
+#endif  // CONFIG_EXT_TILE
+    int min_log2_tile_cols, max_log2_tile_cols;
+    av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols);
 
-  cm->log2_tile_cols =
-      clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
-  cm->log2_tile_rows = cpi->oxcf.tile_rows;
+    cm->log2_tile_cols =
+        clamp(cpi->oxcf.tile_columns, min_log2_tile_cols, max_log2_tile_cols);
+    cm->log2_tile_rows = cpi->oxcf.tile_rows;
 
-  cm->tile_cols = 1 << cm->log2_tile_cols;
-  cm->tile_rows = 1 << cm->log2_tile_rows;
+    cm->tile_cols = 1 << cm->log2_tile_cols;
+    cm->tile_rows = 1 << cm->log2_tile_rows;
 
-  cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
-  cm->tile_width >>= cm->log2_tile_cols;
-  cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
-  cm->tile_height >>= cm->log2_tile_rows;
+    cm->tile_width = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
+    cm->tile_width >>= cm->log2_tile_cols;
+    cm->tile_height = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
+    cm->tile_height >>= cm->log2_tile_rows;
 
-  // round to integer multiples of max superblock size
-  cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
-  cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
+    // round to integer multiples of max superblock size
+    cm->tile_width = ALIGN_POWER_OF_TWO(cm->tile_width, MAX_MIB_SIZE_LOG2);
+    cm->tile_height = ALIGN_POWER_OF_TWO(cm->tile_height, MAX_MIB_SIZE_LOG2);
+#if CONFIG_EXT_TILE
+  }
 #endif  // CONFIG_EXT_TILE
 
 #if CONFIG_DEPENDENT_HORZTILES
   cm->dependent_horz_tiles = cpi->oxcf.dependent_horz_tiles;
 #if CONFIG_EXT_TILE
-  if (cm->tile_rows <= 1) cm->dependent_horz_tiles = 0;
-#else
-  if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
-#endif
-#if CONFIG_TILE_GROUPS
-  if (cpi->oxcf.mtu == 0) {
-    cm->num_tg = cpi->oxcf.num_tile_groups;
+  if (cm->large_scale_tile) {
+    // May not needed since cpi->oxcf.dependent_horz_tiles is already adjusted.
+    cm->dependent_horz_tiles = 0;
   } else {
-    // Use a default value for the purposes of weighting costs in probability
-    // updates
-    cm->num_tg = DEFAULT_MAX_NUM_TG;
+#endif  // CONFIG_EXT_TILE
+    if (cm->log2_tile_rows == 0) cm->dependent_horz_tiles = 0;
+#if CONFIG_EXT_TILE
   }
-  num_tiles_in_tg =
-      (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg;
-  tg_row_start = 0;
-  tg_col_start = 0;
-  for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
-    for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
-      if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) {
-        tg_row_start = tile_row;
-        tg_col_start = tile_col;
-      }
-      cm->tile_group_start_row[tile_row][tile_col] = tg_row_start;
-      cm->tile_group_start_col[tile_row][tile_col] = tg_col_start;
+#endif  // CONFIG_EXT_TILE
+
+#if CONFIG_TILE_GROUPS
+#if CONFIG_EXT_TILE
+  if (!cm->large_scale_tile) {
+#endif  // CONFIG_EXT_TILE
+    if (cpi->oxcf.mtu == 0) {
+      cm->num_tg = cpi->oxcf.num_tile_groups;
+    } else {
+      // Use a default value for the purposes of weighting costs in probability
+      // updates
+      cm->num_tg = DEFAULT_MAX_NUM_TG;
     }
+    num_tiles_in_tg =
+        (cm->tile_cols * cm->tile_rows + cm->num_tg - 1) / cm->num_tg;
+    tg_row_start = 0;
+    tg_col_start = 0;
+    for (tile_row = 0; tile_row < cm->tile_rows; ++tile_row) {
+      for (tile_col = 0; tile_col < cm->tile_cols; ++tile_col) {
+        if ((tile_row * cm->tile_cols + tile_col) % num_tiles_in_tg == 0) {
+          tg_row_start = tile_row;
+          tg_col_start = tile_col;
+        }
+        cm->tile_group_start_row[tile_row][tile_col] = tg_row_start;
+        cm->tile_group_start_col[tile_row][tile_col] = tg_col_start;
+      }
+    }
+#if CONFIG_EXT_TILE
   }
+#endif  // CONFIG_EXT_TILE
 #endif
 #endif
 
@@ -3959,7 +3975,17 @@
 static void loopfilter_frame(AV1_COMP *cpi, AV1_COMMON *cm) {
   MACROBLOCKD *xd = &cpi->td.mb.e_mbd;
   struct loopfilter *lf = &cm->lf;
-  if (is_lossless_requested(&cpi->oxcf)) {
+  int no_loopfilter = 0;
+
+  if (is_lossless_requested(&cpi->oxcf)) no_loopfilter = 1;
+
+#if CONFIG_EXT_TILE
+  // 0 loopfilter level is only necessary if individual tile
+  // decoding is required.
+  if (cm->single_tile_decoding) no_loopfilter = 1;
+#endif  // CONFIG_EXT_TILE
+
+  if (no_loopfilter) {
     lf->filter_level = 0;
   } else {
     struct aom_usec_timer timer;
@@ -4724,7 +4750,8 @@
 #endif
 
 #if CONFIG_EXT_TILE
-  cm->tile_encoding_mode = cpi->oxcf.tile_encoding_mode;
+  cm->large_scale_tile = cpi->oxcf.large_scale_tile;
+  cm->single_tile_decoding = cpi->oxcf.single_tile_decoding;
 #endif  // CONFIG_EXT_TILE
 
 #if CONFIG_XIPHRC