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