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