max-tile: Fix issues discovered when testing max-tile

max-tile remains off by default until more testing is performed but I would
like to check in the fixes that are known so far to prevent this patch getting too big

max_tile was provisionally adopted at the working group meeting 2017-Oct-10

This patch fixes the following issues:
- max_tile is fixed to suport superblock size 64x64 as well as 128x128 (ext_partition support)
- max_tile is fixed in combination with loop_restoration
- max_tile is fixed in combination with ext_tile (Bug: 1013)
- max_tile is fixed in combination with lv_map and 64x64 subperblock (lv_map memory allocation
  fixed for 64x64 superblock)
- max_tile reports the size of the first tile for inspection.c used by the analyzer

Change-Id: Ib83ff613e5d66563c81452a085c7984d3b4813e4
diff --git a/av1/common/alloccommon.c b/av1/common/alloccommon.c
index 33bdf3d..00ff268 100644
--- a/av1/common/alloccommon.c
+++ b/av1/common/alloccommon.c
@@ -135,8 +135,9 @@
   int num_stripes = 0;
   for (int i = 0; i < cm->tile_rows; ++i) {
 #if CONFIG_MAX_TILE
-    const int sb_h = cm->tile_row_start_sb[i + 1] - cm->tile_row_start_sb[i];
-    const int mi_h = sb_h << MAX_MIB_SIZE_LOG2;
+    TileInfo tile_info;
+    av1_tile_set_row(&tile_info, cm, i);
+    const int mi_h = tile_info.mi_row_end - tile_info.mi_row_start;
 #else
     const int mi_h = ((i + 1) < cm->tile_rows)
                          ? cm->tile_height
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index 6c256be..3110240 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -480,6 +480,9 @@
 #if CONFIG_DEPENDENT_HORZTILES
   int tile_row_independent[MAX_TILE_ROWS];  // valid for 0 <= i <  tile_rows
 #endif
+#if CONFIG_EXT_TILE
+  int tile_width, tile_height;  // In MI units
+#endif
 #else
   int log2_tile_cols, log2_tile_rows;  // Used in non-large_scale_tile_coding.
   int tile_width, tile_height;         // In MI units
diff --git a/av1/common/restoration.c b/av1/common/restoration.c
index b898b95..07d4f58 100644
--- a/av1/common/restoration.c
+++ b/av1/common/restoration.c
@@ -41,26 +41,6 @@
 #endif  // MAX_RADIUS == 2
 };
 
-#if CONFIG_MAX_TILE
-static void tile_width_and_height(const AV1_COMMON *cm, int is_uv, int sb_w,
-                                  int sb_h, int *px_w, int *px_h) {
-  const int scaled_sb_w = sb_w << MAX_MIB_SIZE_LOG2;
-  const int scaled_sb_h = sb_h << MAX_MIB_SIZE_LOG2;
-
-  const int ss_x = is_uv && cm->subsampling_x;
-  const int ss_y = is_uv && cm->subsampling_y;
-
-  *px_w = (scaled_sb_w + ss_x) >> ss_x;
-  *px_h = (scaled_sb_h + ss_y) >> ss_y;
-#if CONFIG_FRAME_SUPERRES
-  if (!av1_superres_unscaled(cm)) {
-    av1_calculate_unscaled_superres_size(px_w, px_h,
-                                         cm->superres_scale_denominator);
-  }
-#endif  // CONFIG_FRAME_SUPERRES
-}
-#endif  // CONFIG_MAX_TILE
-
 // Similar to av1_get_tile_rect(), except that we extend the bottommost tile in
 // each frame to a multiple of 8 luma pixels.
 // This is done to help simplify the implementation of striped-loop-restoration,
@@ -93,30 +73,37 @@
   // top-left and we can use get_ext_tile_rect(). With CONFIG_MAX_TILE, we have
   // to do the computation ourselves, iterating over the tiles and keeping
   // track of the largest width and height, then upscaling.
-  int max_sb_w = 0;
-  int max_sb_h = 0;
+  TileInfo tile;
+  int max_mi_w = 0;
+  int max_mi_h = 0;
+  int tile_col = 0;
+  int tile_row = 0;
   for (int i = 0; i < cm->tile_cols; ++i) {
-    const int sb_w = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i];
-    max_sb_w = AOMMAX(max_sb_w, sb_w);
+    av1_tile_set_col(&tile, cm, i);
+    if (tile.mi_col_end - tile.mi_col_start > max_mi_w) {
+      max_mi_w = tile.mi_col_end - tile.mi_col_start;
+      tile_col = i;
+    }
   }
   for (int i = 0; i < cm->tile_rows; ++i) {
-    const int sb_h = cm->tile_row_start_sb[i + 1] - cm->tile_row_start_sb[i];
-    max_sb_h = AOMMAX(max_sb_h, sb_h);
+    av1_tile_set_row(&tile, cm, i);
+    if (tile.mi_row_end - tile.mi_row_start > max_mi_h) {
+      max_mi_h = tile.mi_row_end - tile.mi_row_start;
+      tile_row = i;
+    }
   }
-
-  int max_tile_w, max_tile_h;
-  tile_width_and_height(cm, is_uv, max_sb_w, max_sb_h, &max_tile_w,
-                        &max_tile_h);
+  TileInfo tile_info;
+  av1_tile_init(&tile_info, cm, tile_row, tile_col);
 #else
   TileInfo tile_info;
   av1_tile_init(&tile_info, cm, 0, 0);
+#endif  // CONFIG_MAX_TILE
 
   const AV1PixelRect tile_rect = get_ext_tile_rect(&tile_info, cm, is_uv);
   assert(tile_rect.left == 0 && tile_rect.top == 0);
 
   const int max_tile_w = tile_rect.right;
   const int max_tile_h = tile_rect.bottom;
-#endif  // CONFIG_MAX_TILE
 
   // To calculate hpertile and vpertile (horizontal and vertical units per
   // tile), we basically want to divide the largest tile width or height by the
@@ -1562,8 +1549,8 @@
 // For a vertical index, mi_x should be the block's top row and tile_x_start_sb
 // should be cm->tile_row_start_sb. The return value will be "tile_row" for the
 // tile containing the block.
-static int get_tile_idx(const int *tile_x_start_sb, int mi_x) {
-  int sb_x = mi_x << MAX_MIB_SIZE_LOG2;
+static int get_tile_idx(const int *tile_x_start_sb, int mi_x, int mib_log2) {
+  int sb_x = mi_x >> mib_log2;
 
   for (int i = 0; i < MAX_TILE_COLS; ++i) {
     if (tile_x_start_sb[i + 1] > sb_x) return i;
@@ -1590,22 +1577,13 @@
 // Which tile contains the superblock? Find that tile's top-left in mi-units,
 // together with the tile's size in pixels.
 #if CONFIG_MAX_TILE
-  const int tile_row = get_tile_idx(cm->tile_row_start_sb, mi_row);
-  const int tile_col = get_tile_idx(cm->tile_col_start_sb, mi_col);
-
-  const int sb_t = cm->tile_row_start_sb[tile_row];
-  const int sb_l = cm->tile_col_start_sb[tile_col];
-  const int sb_b = cm->tile_row_start_sb[tile_row + 1];
-  const int sb_r = cm->tile_col_start_sb[tile_col + 1];
-
-  int tile_w, tile_h;
-  tile_width_and_height(cm, is_uv, sb_r - sb_l, sb_t - sb_b, &tile_w, &tile_h);
-
-  const int mi_top = sb_t << MAX_MIB_SIZE_LOG2;
-  const int mi_left = sb_l << MAX_MIB_SIZE_LOG2;
+  const int mib_log2 = cm->mib_size_log2;
+  const int tile_row = get_tile_idx(cm->tile_row_start_sb, mi_row, mib_log2);
+  const int tile_col = get_tile_idx(cm->tile_col_start_sb, mi_col, mib_log2);
 #else
   const int tile_row = mi_row / cm->tile_height;
   const int tile_col = mi_col / cm->tile_width;
+#endif  // CONFIG_MAX_TILE
 
   TileInfo tile_info;
   av1_tile_init(&tile_info, cm, tile_row, tile_col);
@@ -1616,7 +1594,6 @@
 
   const int mi_top = tile_info.mi_row_start;
   const int mi_left = tile_info.mi_col_start;
-#endif  // CONFIG_MAX_TILE
 
   // Compute the mi-unit corners of the superblock relative to the top-left of
   // the tile
diff --git a/av1/common/tile_common.c b/av1/common/tile_common.c
index 5df0410..4612496 100644
--- a/av1/common/tile_common.c
+++ b/av1/common/tile_common.c
@@ -49,10 +49,10 @@
 }
 
 void av1_get_tile_limits(AV1_COMMON *const cm) {
-  int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
-  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
-  int sb_cols = mi_cols >> MAX_MIB_SIZE_LOG2;
-  int sb_rows = mi_rows >> MAX_MIB_SIZE_LOG2;
+  int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
+  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->mib_size_log2);
+  int sb_cols = mi_cols >> cm->mib_size_log2;
+  int sb_rows = mi_rows >> cm->mib_size_log2;
 
   cm->min_log2_tile_cols = tile_log2(MAX_TILE_WIDTH_SB, sb_cols);
   cm->max_log2_tile_cols = tile_log2(1, AOMMIN(sb_cols, MAX_TILE_COLS));
@@ -64,10 +64,10 @@
 }
 
 void av1_calculate_tile_cols(AV1_COMMON *const cm) {
-  int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
-  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
-  int sb_cols = mi_cols >> MAX_MIB_SIZE_LOG2;
-  int sb_rows = mi_rows >> MAX_MIB_SIZE_LOG2;
+  int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, cm->mib_size_log2);
+  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->mib_size_log2);
+  int sb_cols = mi_cols >> cm->mib_size_log2;
+  int sb_rows = mi_rows >> cm->mib_size_log2;
   int i;
 
   if (cm->uniform_tile_spacing_flag) {
@@ -85,7 +85,7 @@
     cm->max_tile_height_sb = sb_rows >> cm->min_log2_tile_rows;
   } else {
     int max_tile_area_sb = (sb_rows * sb_cols);
-    int max_tile_width_sb = 0;
+    int max_tile_width_sb = 1;
     cm->log2_tile_cols = tile_log2(1, cm->tile_cols);
     for (i = 0; i < cm->tile_cols; i++) {
       int size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i];
@@ -99,8 +99,8 @@
 }
 
 void av1_calculate_tile_rows(AV1_COMMON *const cm) {
-  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
-  int sb_rows = mi_rows >> MAX_MIB_SIZE_LOG2;
+  int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, cm->mib_size_log2);
+  int sb_rows = mi_rows >> cm->mib_size_log2;
   int start_sb, size_sb, i;
 
   if (cm->uniform_tile_spacing_flag) {
@@ -131,18 +131,20 @@
 
 void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) {
   assert(row < cm->tile_rows);
-  int mi_row_start = cm->tile_row_start_sb[row] << MAX_MIB_SIZE_LOG2;
-  int mi_row_end = cm->tile_row_start_sb[row + 1] << MAX_MIB_SIZE_LOG2;
+  int mi_row_start = cm->tile_row_start_sb[row] << cm->mib_size_log2;
+  int mi_row_end = cm->tile_row_start_sb[row + 1] << cm->mib_size_log2;
   tile->mi_row_start = mi_row_start;
   tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_rows);
+  assert(tile->mi_row_end > tile->mi_row_start);
 }
 
 void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) {
   assert(col < cm->tile_cols);
-  int mi_col_start = cm->tile_col_start_sb[col] << MAX_MIB_SIZE_LOG2;
-  int mi_col_end = cm->tile_col_start_sb[col + 1] << MAX_MIB_SIZE_LOG2;
+  int mi_col_start = cm->tile_col_start_sb[col] << cm->mib_size_log2;
+  int mi_col_end = cm->tile_col_start_sb[col + 1] << cm->mib_size_log2;
   tile->mi_col_start = mi_col_start;
   tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_cols);
+  assert(tile->mi_col_end > tile->mi_col_start);
 }
 
 #else