Add the max-tile tool with uniform tile support This adds the tool CONFIG_MAX_TILE Uniform tiles are implemented using power of two number of rows or columns. Maximum number of rows or columns is 64 Explicit tiles will follow in a later commit once the command line API is updated for this Change-Id: Ia8d22e7f4aa779448211496c644937afdf037228
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c index fe1c7c2..eef4aa7 100644 --- a/av1/av1_cx_iface.c +++ b/av1/av1_cx_iface.c
@@ -305,8 +305,13 @@ #endif // CONFIG_EXT_PARTITION } else { #endif // CONFIG_EXT_TILE +#if CONFIG_MAX_TILE RANGE_CHECK_HI(extra_cfg, tile_columns, 6); - RANGE_CHECK_HI(extra_cfg, tile_rows, 2); + RANGE_CHECK_HI(extra_cfg, tile_rows, 6); +#else // CONFIG_MAX_TILE + RANGE_CHECK_HI(extra_cfg, tile_columns, 6); + RANGE_CHECK_HI(extra_cfg, tile_rows, 2); +#endif // CONFIG_MAX_TILE #if CONFIG_EXT_TILE } #endif // CONFIG_EXT_TILE
diff --git a/av1/common/enums.h b/av1/common/enums.h index 15e7d9c..843e290 100644 --- a/av1/common/enums.h +++ b/av1/common/enums.h
@@ -67,8 +67,13 @@ #define MAX_TILE_ROWS 1024 #define MAX_TILE_COLS 1024 #else +#if CONFIG_MAX_TILE +#define MAX_TILE_ROWS 64 +#define MAX_TILE_COLS 64 +#else #define MAX_TILE_ROWS 4 #define MAX_TILE_COLS 64 +#endif #endif // CONFIG_EXT_TILE #if CONFIG_VAR_TX
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h index 1a792fb..e538502 100644 --- a/av1/common/onyxc_int.h +++ b/av1/common/onyxc_int.h
@@ -415,10 +415,27 @@ int error_resilient_mode; - int log2_tile_cols, log2_tile_rows; // Used in non-large_scale_tile_coding. int tile_cols, tile_rows; int last_tile_cols, last_tile_rows; - int tile_width, tile_height; // In MI units + +#if CONFIG_MAX_TILE + int min_log2_tile_cols; + int max_log2_tile_cols; + int max_log2_tile_rows; + int min_log2_tile_rows; + int min_log2_tiles; + int max_tile_width_sb; + int max_tile_height_sb; + int uniform_tile_spacing_flag; + int log2_tile_cols; // only valid for uniform tiles + int log2_tile_rows; // only valid for uniform tiles + int tile_col_start_sb[MAX_TILE_COLS + 1]; // valid for 0 <= i <= tile_cols + int tile_row_start_sb[MAX_TILE_ROWS + 1]; // valid for 0 <= i <= tile_rows +#else + int log2_tile_cols, log2_tile_rows; // Used in non-large_scale_tile_coding. + int tile_width, tile_height; // In MI units +#endif // CONFIG_MAX_TILE + #if CONFIG_EXT_TILE unsigned int large_scale_tile; unsigned int single_tile_decoding;
diff --git a/av1/common/tile_common.c b/av1/common/tile_common.c index 75e7d6a..f73c39c 100644 --- a/av1/common/tile_common.c +++ b/av1/common/tile_common.c
@@ -13,16 +13,6 @@ #include "av1/common/onyxc_int.h" #include "aom_dsp/aom_dsp_common.h" -void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) { - tile->mi_row_start = row * cm->tile_height; - tile->mi_row_end = AOMMIN(tile->mi_row_start + cm->tile_height, cm->mi_rows); -} - -void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) { - tile->mi_col_start = col * cm->tile_width; - tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols); -} - #if CONFIG_DEPENDENT_HORZTILES void av1_tile_set_tg_boundary(TileInfo *tile, const AV1_COMMON *const cm, int row, int col) { @@ -46,6 +36,112 @@ #endif } +#if CONFIG_MAX_TILE + +// Find smallest k>=0 such that (blk_size << k) >= target +static int tile_log2(int blk_size, int target) { + int k; + for (k = 0; (blk_size << k) < target; k++) { + } + return k; +} + +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; + + cm->min_log2_tile_cols = tile_log2(MAX_TILE_WIDTH_SB, sb_cols); + cm->max_log2_tile_cols = tile_log2(1, sb_cols); + cm->max_log2_tile_rows = tile_log2(1, sb_rows); + cm->min_log2_tiles = tile_log2(MAX_TILE_AREA_SB, sb_cols * sb_rows); + cm->min_log2_tiles = AOMMAX(cm->min_log2_tiles, cm->min_log2_tile_cols); + // TODO(dominic.symes@arm.com): + // Add in levelMinLog2Tiles as a lower limit when levels are defined +} + +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 i; + + if (cm->uniform_tile_spacing_flag) { + int start_sb; + int size_sb = ALIGN_POWER_OF_TWO(sb_cols, cm->log2_tile_cols); + size_sb >>= cm->log2_tile_cols; + assert(size_sb > 0); + for (i = 0, start_sb = 0; start_sb < sb_cols; i++) { + cm->tile_col_start_sb[i] = start_sb; + start_sb += size_sb; + } + cm->tile_cols = i; + cm->tile_col_start_sb[i] = start_sb; + cm->min_log2_tile_rows = AOMMAX(cm->min_log2_tiles - cm->log2_tile_cols, 0); + } else { + int max_tile_area_sb = (sb_rows * sb_cols); + int max_tile_width_sb = 0; + for (i = 0; i < cm->tile_cols; i++) { + int size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i]; + max_tile_width_sb = AOMMAX(max_tile_width_sb, size_sb); + } + if (cm->min_log2_tiles) { + max_tile_area_sb >>= (cm->min_log2_tiles + 1); + } + cm->max_tile_height_sb = AOMMAX(max_tile_area_sb / max_tile_width_sb, 1); + } +} + +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 start_sb, size_sb, i; + + if (cm->uniform_tile_spacing_flag) { + size_sb = ALIGN_POWER_OF_TWO(sb_rows, cm->log2_tile_rows); + size_sb >>= cm->log2_tile_rows; + assert(size_sb > 0); + for (i = 0, start_sb = 0; start_sb < sb_rows; i++) { + cm->tile_row_start_sb[i] = start_sb; + start_sb += size_sb; + } + cm->tile_rows = i; + cm->tile_row_start_sb[i] = start_sb; + } else { + // No action + } +} + +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; + tile->mi_row_start = mi_row_start; + tile->mi_row_end = AOMMIN(mi_row_end, cm->mi_rows); +} + +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; + tile->mi_col_start = mi_col_start; + tile->mi_col_end = AOMMIN(mi_col_end, cm->mi_cols); +} + +#else + +void av1_tile_set_row(TileInfo *tile, const AV1_COMMON *cm, int row) { + tile->mi_row_start = row * cm->tile_height; + tile->mi_row_end = AOMMIN(tile->mi_row_start + cm->tile_height, cm->mi_rows); +} + +void av1_tile_set_col(TileInfo *tile, const AV1_COMMON *cm, int col) { + tile->mi_col_start = col * cm->tile_width; + tile->mi_col_end = AOMMIN(tile->mi_col_start + cm->tile_width, cm->mi_cols); +} + #if CONFIG_EXT_PARTITION #define MIN_TILE_WIDTH_MAX_SB 2 #define MAX_TILE_WIDTH_MAX_SB 32 @@ -74,6 +170,7 @@ *max_log2_tile_cols = get_max_log2_tile_cols(max_sb_cols); assert(*min_log2_tile_cols <= *max_log2_tile_cols); } +#endif // CONFIG_MAX_TILE void av1_setup_frame_boundary_info(const AV1_COMMON *const cm) { MODE_INFO *mi = cm->mi;
diff --git a/av1/common/tile_common.h b/av1/common/tile_common.h index 0bc80c9..a455957 100644 --- a/av1/common/tile_common.h +++ b/av1/common/tile_common.h
@@ -54,6 +54,21 @@ int av1_disable_loopfilter_on_tile_boundary(const struct AV1Common *cm); #endif // CONFIG_LOOPFILTERING_ACROSS_TILES +#if CONFIG_MAX_TILE + +// Define tile maximum width and area +// There is no maximum height since height is limited by area and width limits +// The minimum tile width or height is fixed at one superblock +#define MAX_TILE_WIDTH (4096) // Max Tile width in pixels +#define MAX_TILE_WIDTH_SB (MAX_TILE_WIDTH >> MAX_SB_SIZE_LOG2) +#define MAX_TILE_AREA (4096 * 2304) // Maximum tile area in pixels +#define MAX_TILE_AREA_SB (MAX_TILE_AREA >> (2 * MAX_SB_SIZE_LOG2)) + +void av1_get_tile_limits(struct AV1Common *const cm); +void av1_calculate_tile_cols(struct AV1Common *const cm); +void av1_calculate_tile_rows(struct AV1Common *const cm); +#endif + #ifdef __cplusplus } // extern "C" #endif
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c index fcad912..f1b19af 100644 --- a/av1/decoder/decodeframe.c +++ b/av1/decoder/decodeframe.c
@@ -3154,6 +3154,76 @@ "Tile group extends past last tile in frame"); } +#if CONFIG_MAX_TILE + +// Same function as av1_read_uniform but reading from uncompresses header wb +static int rb_read_uniform(struct aom_read_bit_buffer *const rb, int n) { + const int l = get_unsigned_bits(n); + const int m = (1 << l) - n; + const int v = aom_rb_read_literal(rb, l - 1); + assert(l != 0); + if (v < m) + return v; + else + return (v << 1) - m + aom_rb_read_literal(rb, 1); +} + +static void read_tile_info_max_tile(AV1_COMMON *const cm, + struct aom_read_bit_buffer *const rb) { + int width_mi = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2); + int height_mi = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2); + int width_sb = width_mi >> MAX_MIB_SIZE_LOG2; + int height_sb = height_mi >> MAX_MIB_SIZE_LOG2; + int start_sb, size_sb, i; + + av1_get_tile_limits(cm); + cm->uniform_tile_spacing_flag = aom_rb_read_bit(rb); + + // Read tile columns + if (cm->uniform_tile_spacing_flag) { + cm->log2_tile_cols = cm->min_log2_tile_cols; + while (cm->log2_tile_cols < cm->max_log2_tile_cols) { + if (!aom_rb_read_bit(rb)) { + break; + } + cm->log2_tile_cols++; + } + } else { + for (i = 0, start_sb = 0; width_sb > 0; i++) { + size_sb = 1 + rb_read_uniform(rb, AOMMIN(width_sb, MAX_TILE_WIDTH_SB)); + cm->tile_col_start_sb[i] = start_sb; + start_sb += size_sb; + width_sb -= size_sb; + } + cm->tile_cols = i; + cm->tile_col_start_sb[i] = start_sb; + } + av1_calculate_tile_cols(cm); + + // Read tile rows + if (cm->uniform_tile_spacing_flag) { + cm->log2_tile_rows = cm->min_log2_tile_rows; + while (cm->log2_tile_rows < cm->max_log2_tile_rows) { + if (!aom_rb_read_bit(rb)) { + break; + } + cm->log2_tile_rows++; + } + } else { + for (i = 0, start_sb = 0; height_sb > 0; i++) { + size_sb = + 1 + rb_read_uniform(rb, AOMMIN(height_sb, cm->max_tile_height_sb)); + cm->tile_row_start_sb[i] = start_sb; + start_sb += size_sb; + height_sb -= size_sb; + } + cm->tile_rows = i; + cm->tile_row_start_sb[i] = start_sb; + } + av1_calculate_tile_rows(cm); +} +#endif + static void read_tile_info(AV1Decoder *const pbi, struct aom_read_bit_buffer *const rb) { AV1_COMMON *const cm = &pbi->common; @@ -3205,23 +3275,37 @@ #endif } else { #endif // CONFIG_EXT_TILE - int min_log2_tile_cols, max_log2_tile_cols, max_ones; - av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - // columns - max_ones = max_log2_tile_cols - min_log2_tile_cols; - cm->log2_tile_cols = min_log2_tile_cols; - while (max_ones-- && aom_rb_read_bit(rb)) cm->log2_tile_cols++; +#if CONFIG_MAX_TILE + read_tile_info_max_tile(cm, rb); +#else + int min_log2_tile_cols, max_log2_tile_cols, max_ones; + av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - if (cm->log2_tile_cols > 6) - aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, - "Invalid number of tile columns"); + // columns + max_ones = max_log2_tile_cols - min_log2_tile_cols; + cm->log2_tile_cols = min_log2_tile_cols; + while (max_ones-- && aom_rb_read_bit(rb)) cm->log2_tile_cols++; - // rows - cm->log2_tile_rows = aom_rb_read_bit(rb); - if (cm->log2_tile_rows) cm->log2_tile_rows += aom_rb_read_bit(rb); + if (cm->log2_tile_cols > 6) + aom_internal_error(&cm->error, AOM_CODEC_CORRUPT_FRAME, + "Invalid number of tile columns"); + + // rows + cm->log2_tile_rows = aom_rb_read_bit(rb); + if (cm->log2_tile_rows) cm->log2_tile_rows += aom_rb_read_bit(rb); + + cm->tile_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols); + cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_tile_rows); + + const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width; + const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_height; + + cm->tile_cols = AOMMIN(1 << cm->log2_tile_cols, max_cols); + cm->tile_rows = AOMMIN(1 << cm->log2_tile_rows, max_rows); +#endif // CONFIG_MAX_TILE #if CONFIG_DEPENDENT_HORZTILES - if (cm->log2_tile_rows != 0) + if (cm->tile_rows > 1) cm->dependent_horz_tiles = aom_rb_read_bit(rb); else cm->dependent_horz_tiles = 0; @@ -3230,15 +3314,6 @@ cm->loop_filter_across_tiles_enabled = aom_rb_read_bit(rb); #endif // CONFIG_LOOPFILTERING_ACROSS_TILES - cm->tile_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols); - cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_tile_rows); - - const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width; - const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_height; - - cm->tile_cols = AOMMIN(1 << cm->log2_tile_cols, max_cols); - cm->tile_rows = AOMMIN(1 << cm->log2_tile_rows, max_rows); - // tile size magnitude pbi->tile_size_bytes = aom_rb_read_literal(rb, 2) + 1; #if CONFIG_EXT_TILE
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c index 4b72fb2..07a28e4 100644 --- a/av1/encoder/bitstream.c +++ b/av1/encoder/bitstream.c
@@ -3601,6 +3601,72 @@ } } +#if CONFIG_MAX_TILE + +// Same function as write_uniform but writing to uncompresses header wb +static void wb_write_uniform(struct aom_write_bit_buffer *wb, int n, int v) { + const int l = get_unsigned_bits(n); + const int m = (1 << l) - n; + if (l == 0) return; + if (v < m) { + aom_wb_write_literal(wb, v, l - 1); + } else { + aom_wb_write_literal(wb, m + ((v - m) >> 1), l - 1); + aom_wb_write_literal(wb, (v - m) & 1, 1); + } +} + +static void write_tile_info_max_tile(const AV1_COMMON *const cm, + struct aom_write_bit_buffer *wb) { + int width_mi = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2); + int height_mi = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2); + int width_sb = width_mi >> MAX_MIB_SIZE_LOG2; + int height_sb = height_mi >> MAX_MIB_SIZE_LOG2; + int size_sb, i; + + aom_wb_write_bit(wb, cm->uniform_tile_spacing_flag); + + if (cm->uniform_tile_spacing_flag) { + // Uniform spaced tiles with power-of-two number of rows and columns + // tile columns + int ones = cm->log2_tile_cols - cm->min_log2_tile_cols; + while (ones--) { + aom_wb_write_bit(wb, 1); + } + if (cm->log2_tile_cols < cm->max_log2_tile_cols) { + aom_wb_write_bit(wb, 0); + } + + // rows + ones = cm->log2_tile_rows - cm->min_log2_tile_rows; + while (ones--) { + aom_wb_write_bit(wb, 1); + } + if (cm->log2_tile_rows < cm->max_log2_tile_rows) { + aom_wb_write_bit(wb, 0); + } + } else { + // Explicit tiles with configurable tile widths and heights + // columns + for (i = 0; i < cm->tile_cols; i++) { + size_sb = cm->tile_col_start_sb[i + 1] - cm->tile_col_start_sb[i]; + wb_write_uniform(wb, AOMMIN(width_sb, MAX_TILE_WIDTH_SB), size_sb - 1); + width_sb -= size_sb; + } + assert(width_sb == 0); + + // rows + for (i = 0; i < cm->tile_rows; i++) { + size_sb = cm->tile_row_start_sb[i + 1] - cm->tile_row_start_sb[i]; + wb_write_uniform(wb, AOMMIN(height_sb, cm->max_tile_height_sb), + size_sb - 1); + height_sb -= size_sb; + } + assert(height_sb == 0); + } +} +#endif + static void write_tile_info(const AV1_COMMON *const cm, struct aom_write_bit_buffer *wb) { #if CONFIG_EXT_TILE @@ -3633,20 +3699,25 @@ #endif // CONFIG_EXT_PARTITION } else { #endif // CONFIG_EXT_TILE - int min_log2_tile_cols, max_log2_tile_cols, ones; - av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - // columns - ones = cm->log2_tile_cols - min_log2_tile_cols; - while (ones--) aom_wb_write_bit(wb, 1); +#if CONFIG_MAX_TILE + write_tile_info_max_tile(cm, wb); +#else + int min_log2_tile_cols, max_log2_tile_cols, ones; + av1_get_tile_n_bits(cm->mi_cols, &min_log2_tile_cols, &max_log2_tile_cols); - if (cm->log2_tile_cols < max_log2_tile_cols) aom_wb_write_bit(wb, 0); + // columns + ones = cm->log2_tile_cols - min_log2_tile_cols; + while (ones--) aom_wb_write_bit(wb, 1); - // rows - aom_wb_write_bit(wb, cm->log2_tile_rows != 0); - if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); + if (cm->log2_tile_cols < max_log2_tile_cols) aom_wb_write_bit(wb, 0); + + // rows + aom_wb_write_bit(wb, cm->log2_tile_rows != 0); + if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->log2_tile_rows != 1); +#endif #if CONFIG_DEPENDENT_HORZTILES - if (cm->log2_tile_rows != 0) aom_wb_write_bit(wb, cm->dependent_horz_tiles); + if (cm->tile_rows > 1) aom_wb_write_bit(wb, cm->dependent_horz_tiles); #endif #if CONFIG_EXT_TILE }
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 858c9af..0fcc8e6 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -863,6 +863,33 @@ #endif } +#if CONFIG_MAX_TILE + +static void set_tile_info_max_tile(AV1_COMP *cpi) { + AV1_COMMON *const cm = &cpi->common; + + av1_get_tile_limits(cm); + // Configure uniform spaced tiles + // (API is not yet upgraded to general tiles) + cm->uniform_tile_spacing_flag = 1; + + // configure tile columns + if (cm->uniform_tile_spacing_flag) { + cm->log2_tile_cols = AOMMAX(cpi->oxcf.tile_columns, cm->min_log2_tile_cols); + cm->log2_tile_cols = AOMMIN(cm->log2_tile_cols, cm->max_log2_tile_cols); + } + av1_calculate_tile_cols(cm); + + // configure tile rows + if (cm->uniform_tile_spacing_flag) { + cm->log2_tile_rows = AOMMAX(cpi->oxcf.tile_rows, cm->min_log2_tile_rows); + cm->log2_tile_rows = AOMMIN(cm->log2_tile_rows, cm->max_log2_tile_rows); + } + av1_calculate_tile_rows(cm); +} + +#endif + static void set_tile_info(AV1_COMP *cpi) { AV1_COMMON *const cm = &cpi->common; #if CONFIG_DEPENDENT_HORZTILES @@ -904,21 +931,26 @@ 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; +#if CONFIG_MAX_TILE + set_tile_info_max_tile(cpi); +#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_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols); - cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_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; - const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width; - const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_height; + cm->tile_width = get_tile_size(cm->mi_cols, cm->log2_tile_cols); + cm->tile_height = get_tile_size(cm->mi_rows, cm->log2_tile_rows); - cm->tile_cols = AOMMIN(1 << cm->log2_tile_cols, max_cols); - cm->tile_rows = AOMMIN(1 << cm->log2_tile_rows, max_rows); + const int max_cols = (cm->mi_cols + cm->tile_width - 1) / cm->tile_width; + const int max_rows = (cm->mi_rows + cm->tile_height - 1) / cm->tile_height; + + cm->tile_cols = AOMMIN(1 << cm->log2_tile_cols, max_cols); + cm->tile_rows = AOMMIN(1 << cm->log2_tile_rows, max_rows); +#endif // CONFIG_MAX_TILE #if CONFIG_EXT_TILE } #endif // CONFIG_EXT_TILE
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake index 05934e9..9ee628b 100644 --- a/build/cmake/aom_config_defaults.cmake +++ b/build/cmake/aom_config_defaults.cmake
@@ -165,6 +165,7 @@ set(CONFIG_LPF_DIRECT 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_LV_MAP 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_MASKED_TX 0 CACHE NUMBER "AV1 experiment flag.") +set(CONFIG_MAX_TILE 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_MFMV 0 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_MOTION_VAR 1 CACHE NUMBER "AV1 experiment flag.") set(CONFIG_MRC_TX 0 CACHE NUMBER "AV1 experiment flag.")
diff --git a/configure b/configure index 1af3e85..273b6a0 100755 --- a/configure +++ b/configure
@@ -342,6 +342,7 @@ loopfilter_level no_frame_context_signaling txmg + max_tile hash_me colorspace_headers mfmv