Commit 26ad0b22 authored by Dominic Symes's avatar Dominic Symes

MAX_TILE: Allow list of tile widths/heights

The aomenc API is modified to allow --tile_width and --tile_height to take a list of sizes.
For example, --tile_width=2,3 will give tiles of widths 2,3,2,3,... until the image width
is exhausted. --tile_width=2 will still work to gives tiles of width 2.

Change-Id: I2afa14d404557aa8b7341b20f7477590e03e0bdb
parent 80dd4b94
...@@ -619,6 +619,48 @@ typedef struct aom_codec_enc_cfg { ...@@ -619,6 +619,48 @@ typedef struct aom_codec_enc_cfg {
* implies a large-scale tile coding. * implies a large-scale tile coding.
*/ */
unsigned int large_scale_tile; unsigned int large_scale_tile;
/*!\brief Number of explicit tile widths specified
*
* This value indicates the number of tile widths specified
* A value of 0 implies no tile widths are specified.
* Tile widths are given in the array tile_widths[]
*/
int tile_width_count;
/*!\brief Number of explicit tile heights specified
*
* This value indicates the number of tile heights specified
* A value of 0 implies no tile heights are specified.
* Tile heights are given in the array tile_heights[]
*/
int tile_height_count;
/*!\brief Maximum number of tile widths in tile widths array
*
* This define gives the maximum number of elements in the tile_widths array.
*/
#define MAX_TILE_WIDTHS 64 // maximum tile width array length
/*!\brief Array of specified tile widths
*
* This array specifies tile widths (and may be empty)
* The number of widths specified is given by tile_width_count
*/
int tile_widths[MAX_TILE_WIDTHS];
/*!\brief Maximum number of tile heights in tile heights array.
*
* This define gives the maximum number of elements in the tile_heights array.
*/
#define MAX_TILE_HEIGHTS 64 // maximum tile height array length
/*!\brief Array of specified tile heights
*
* This array specifies tile heights (and may be empty)
* The number of heights specified is given by tile_height_count
*/
int tile_heights[MAX_TILE_HEIGHTS];
} aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */ } aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */
/*!\brief Initialize an encoder instance /*!\brief Initialize an encoder instance
......
...@@ -492,26 +492,6 @@ enum aome_enc_control_id { ...@@ -492,26 +492,6 @@ enum aome_enc_control_id {
*/ */
AV1E_SET_MTU, AV1E_SET_MTU,
/*!\brief Codec control function to set tile_width.
*
* In encoding this sets expilcit tiles of the given tile width
*
* By default, the value is 0 and explicit tiles are disabled.
*
* Experiment: MAX_TILE
*/
AV1E_SET_TILE_WIDTH,
/*!\brief Codec control function to set tile_height.
*
* In encoding this sets expilcit tiles of the given tile height
*
* By default, the value is 0 and explicit tiles are disabled.
*
* Experiment: MAX_TILE
*/
AV1E_SET_TILE_HEIGHT,
/*!\brief Codec control function to set dependent_horz_tiles. /*!\brief Codec control function to set dependent_horz_tiles.
* *
* In encoding and decoding, AV1 allows enabling dependent horizontal tile * In encoding and decoding, AV1 allows enabling dependent horizontal tile
......
...@@ -414,9 +414,9 @@ static const arg_def_t tile_rows = ...@@ -414,9 +414,9 @@ static const arg_def_t tile_rows =
"Number of tile rows to use, log2 (set to 0 while threads > 1)"); "Number of tile rows to use, log2 (set to 0 while threads > 1)");
#if CONFIG_MAX_TILE #if CONFIG_MAX_TILE
static const arg_def_t tile_width = static const arg_def_t tile_width =
ARG_DEF(NULL, "tile-width", 1, "Width of each tile"); ARG_DEF(NULL, "tile-width", 1, "Tile widths (comma separated)");
static const arg_def_t tile_height = static const arg_def_t tile_height =
ARG_DEF(NULL, "tile-height", 1, "Height of each tile"); ARG_DEF(NULL, "tile-height", 1, "Tile heights (command separated)");
#endif #endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
static const arg_def_t tile_dependent_rows = static const arg_def_t tile_dependent_rows =
...@@ -553,10 +553,6 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1, ...@@ -553,10 +553,6 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
&tile_cols, &tile_cols,
&tile_rows, &tile_rows,
#if CONFIG_MAX_TILE
&tile_width,
&tile_height,
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
&tile_dependent_rows, &tile_dependent_rows,
#endif #endif
...@@ -614,10 +610,6 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED, ...@@ -614,10 +610,6 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
AV1E_SET_TILE_COLUMNS, AV1E_SET_TILE_COLUMNS,
AV1E_SET_TILE_ROWS, AV1E_SET_TILE_ROWS,
#if CONFIG_MAX_TILE
AV1E_SET_TILE_WIDTH,
AV1E_SET_TILE_HEIGHT,
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
AV1E_SET_TILE_DEPENDENT_ROWS, AV1E_SET_TILE_DEPENDENT_ROWS,
#endif #endif
...@@ -1119,6 +1111,14 @@ static int parse_stream_params(struct AvxEncoderConfig *global, ...@@ -1119,6 +1111,14 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
config->cfg.kf_max_dist = arg_parse_uint(&arg); config->cfg.kf_max_dist = arg_parse_uint(&arg);
} else if (arg_match(&arg, &kf_disabled, argi)) { } else if (arg_match(&arg, &kf_disabled, argi)) {
config->cfg.kf_mode = AOM_KF_DISABLED; config->cfg.kf_mode = AOM_KF_DISABLED;
#if CONFIG_MAX_TILE
} else if (arg_match(&arg, &tile_width, argi)) {
config->cfg.tile_width_count =
arg_parse_list(&arg, config->cfg.tile_widths, MAX_TILE_WIDTHS);
} else if (arg_match(&arg, &tile_height, argi)) {
config->cfg.tile_height_count =
arg_parse_list(&arg, config->cfg.tile_heights, MAX_TILE_HEIGHTS);
#endif
} else { } else {
int i, match = 0; int i, match = 0;
for (i = 0; ctrl_args[i]; i++) { for (i = 0; ctrl_args[i]; i++) {
......
...@@ -210,3 +210,28 @@ int arg_parse_enum_or_int(const struct arg *arg) { ...@@ -210,3 +210,28 @@ int arg_parse_enum_or_int(const struct arg *arg) {
if (arg->def->enums) return arg_parse_enum(arg); if (arg->def->enums) return arg_parse_enum(arg);
return arg_parse_int(arg); return arg_parse_int(arg);
} }
// parse a comma separated list of at most n integers
// return the number of elements in the list
int arg_parse_list(const struct arg *arg, int *list, int n) {
const char *ptr = arg->val;
char *endptr;
int i = 0;
while (ptr[0] != '\0') {
int32_t rawval = (int32_t)strtol(ptr, &endptr, 10);
if (rawval < INT_MIN || rawval > INT_MAX) {
die("Option %s: Value %ld out of range for signed int\n", arg->name,
rawval);
} else if (i >= n) {
die("Option %s: List has more than %d entries\n", arg->name, n);
} else if (*endptr == ',') {
endptr++;
} else if (*endptr != '\0') {
die("Option %s: Bad list separator '%c'\n", arg->name, *endptr);
}
list[i++] = (int)rawval;
ptr = endptr;
}
return i;
}
...@@ -57,6 +57,7 @@ int arg_parse_int(const struct arg *arg); ...@@ -57,6 +57,7 @@ int arg_parse_int(const struct arg *arg);
struct aom_rational arg_parse_rational(const struct arg *arg); struct aom_rational arg_parse_rational(const struct arg *arg);
int arg_parse_enum(const struct arg *arg); int arg_parse_enum(const struct arg *arg);
int arg_parse_enum_or_int(const struct arg *arg); int arg_parse_enum_or_int(const struct arg *arg);
int arg_parse_list(const struct arg *arg, int *list, int n);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif
......
...@@ -36,10 +36,6 @@ struct av1_extracfg { ...@@ -36,10 +36,6 @@ struct av1_extracfg {
unsigned int static_thresh; unsigned int static_thresh;
unsigned int tile_columns; // log2 number of tile columns unsigned int tile_columns; // log2 number of tile columns
unsigned int tile_rows; // log2 number of tile rows unsigned int tile_rows; // log2 number of tile rows
#if CONFIG_MAX_TILE
unsigned int tile_width; // tile width in superblocks (if non zero)
unsigned int tile_height; // tile height in superblocks (if non zero)
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
unsigned int dependent_horz_tiles; unsigned int dependent_horz_tiles;
#endif #endif
...@@ -105,10 +101,6 @@ static struct av1_extracfg default_extra_cfg = { ...@@ -105,10 +101,6 @@ static struct av1_extracfg default_extra_cfg = {
0, // static_thresh 0, // static_thresh
0, // tile_columns 0, // tile_columns
0, // tile_rows 0, // tile_rows
#if CONFIG_MAX_TILE
0, // tile_width
0, // tile_height
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
0, // Dependent Horizontal tiles 0, // Dependent Horizontal tiles
#endif #endif
...@@ -316,7 +308,6 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx, ...@@ -316,7 +308,6 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
#if CONFIG_MAX_TILE #if CONFIG_MAX_TILE
RANGE_CHECK_HI(extra_cfg, tile_columns, 6); RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 6); RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
RANGE_CHECK_HI(extra_cfg, tile_width, MAX_TILE_WIDTH_SB);
#else // CONFIG_MAX_TILE #else // CONFIG_MAX_TILE
RANGE_CHECK_HI(extra_cfg, tile_columns, 6); RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 2); RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
...@@ -639,8 +630,14 @@ static aom_codec_err_t set_encoder_config( ...@@ -639,8 +630,14 @@ static aom_codec_err_t set_encoder_config(
#endif // CONFIG_EXT_TILE #endif // CONFIG_EXT_TILE
#if CONFIG_MAX_TILE #if CONFIG_MAX_TILE
oxcf->tile_width = extra_cfg->tile_width; oxcf->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
oxcf->tile_height = extra_cfg->tile_height; oxcf->tile_height_count = AOMMIN(cfg->tile_height_count, MAX_TILE_ROWS);
for (int i = 0; i < oxcf->tile_width_count; i++) {
oxcf->tile_widths[i] = AOMMAX(cfg->tile_widths[i], 1);
}
for (int i = 0; i < oxcf->tile_height_count; i++) {
oxcf->tile_heights[i] = AOMMAX(cfg->tile_heights[i], 1);
}
#endif #endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
oxcf->dependent_horz_tiles = oxcf->dependent_horz_tiles =
...@@ -787,21 +784,6 @@ static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx, ...@@ -787,21 +784,6 @@ static aom_codec_err_t ctrl_set_tile_rows(aom_codec_alg_priv_t *ctx,
return update_extra_cfg(ctx, &extra_cfg); return update_extra_cfg(ctx, &extra_cfg);
} }
#if CONFIG_MAX_TILE
static aom_codec_err_t ctrl_set_tile_width(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.tile_width = CAST(AV1E_SET_TILE_WIDTH, args);
return update_extra_cfg(ctx, &extra_cfg);
}
static aom_codec_err_t ctrl_set_tile_height(aom_codec_alg_priv_t *ctx,
va_list args) {
struct av1_extracfg extra_cfg = ctx->extra_cfg;
extra_cfg.tile_height = CAST(AV1E_SET_TILE_HEIGHT, args);
return update_extra_cfg(ctx, &extra_cfg);
}
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx, static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx,
va_list args) { va_list args) {
...@@ -1582,10 +1564,6 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { ...@@ -1582,10 +1564,6 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh }, { AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
{ AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns }, { AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
{ AV1E_SET_TILE_ROWS, ctrl_set_tile_rows }, { AV1E_SET_TILE_ROWS, ctrl_set_tile_rows },
#if CONFIG_MAX_TILE
{ AV1E_SET_TILE_WIDTH, ctrl_set_tile_width },
{ AV1E_SET_TILE_HEIGHT, ctrl_set_tile_height },
#endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
{ AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows }, { AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows },
#endif #endif
...@@ -1701,6 +1679,10 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = { ...@@ -1701,6 +1679,10 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
0, // kf_min_dist 0, // kf_min_dist
9999, // kf_max_dist 9999, // kf_max_dist
0, // large_scale_tile 0, // large_scale_tile
0, // tile_width_count
0, // tile_height_count
{ 0 }, // tile_widths
{ 0 }, // tile_heights
} }, } },
}; };
......
...@@ -927,18 +927,20 @@ static void set_tile_info_max_tile(AV1_COMP *cpi) { ...@@ -927,18 +927,20 @@ static void set_tile_info_max_tile(AV1_COMP *cpi) {
av1_get_tile_limits(cm); av1_get_tile_limits(cm);
// configure tile columns // configure tile columns
if (cpi->oxcf.tile_width == 0 || cpi->oxcf.tile_height == 0) { if (cpi->oxcf.tile_width_count == 0 || cpi->oxcf.tile_height_count == 0) {
cm->uniform_tile_spacing_flag = 1; cm->uniform_tile_spacing_flag = 1;
cm->log2_tile_cols = AOMMAX(cpi->oxcf.tile_columns, cm->min_log2_tile_cols); 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); cm->log2_tile_cols = AOMMIN(cm->log2_tile_cols, cm->max_log2_tile_cols);
} else { } else {
int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2); int mi_cols = ALIGN_POWER_OF_TWO(cm->mi_cols, MAX_MIB_SIZE_LOG2);
int sb_cols = mi_cols >> MAX_MIB_SIZE_LOG2; int sb_cols = mi_cols >> MAX_MIB_SIZE_LOG2;
int size_sb = AOMMIN(cpi->oxcf.tile_width, MAX_TILE_WIDTH_SB); int size_sb, j = 0;
cm->uniform_tile_spacing_flag = 0; cm->uniform_tile_spacing_flag = 0;
for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) { for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
cm->tile_col_start_sb[i] = start_sb; cm->tile_col_start_sb[i] = start_sb;
start_sb += size_sb; size_sb = cpi->oxcf.tile_widths[j++];
if (j >= cpi->oxcf.tile_width_count) j = 0;
start_sb += AOMMIN(size_sb, MAX_TILE_WIDTH_SB);
} }
cm->tile_cols = i; cm->tile_cols = i;
cm->tile_col_start_sb[i] = sb_cols; cm->tile_col_start_sb[i] = sb_cols;
...@@ -952,10 +954,12 @@ static void set_tile_info_max_tile(AV1_COMP *cpi) { ...@@ -952,10 +954,12 @@ static void set_tile_info_max_tile(AV1_COMP *cpi) {
} else { } else {
int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2); int mi_rows = ALIGN_POWER_OF_TWO(cm->mi_rows, MAX_MIB_SIZE_LOG2);
int sb_rows = mi_rows >> MAX_MIB_SIZE_LOG2; int sb_rows = mi_rows >> MAX_MIB_SIZE_LOG2;
int size_sb = AOMMIN(cpi->oxcf.tile_height, cm->max_tile_height_sb); int size_sb, j = 0;
for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) { for (i = 0, start_sb = 0; start_sb < sb_rows && i < MAX_TILE_ROWS; i++) {
cm->tile_row_start_sb[i] = start_sb; cm->tile_row_start_sb[i] = start_sb;
start_sb += size_sb; size_sb = cpi->oxcf.tile_heights[j++];
if (j >= cpi->oxcf.tile_height_count) j = 0;
start_sb += AOMMIN(size_sb, cm->max_tile_height_sb);
} }
cm->tile_rows = i; cm->tile_rows = i;
cm->tile_row_start_sb[i] = sb_rows; cm->tile_row_start_sb[i] = sb_rows;
......
...@@ -266,8 +266,10 @@ typedef struct AV1EncoderConfig { ...@@ -266,8 +266,10 @@ typedef struct AV1EncoderConfig {
int tile_columns; int tile_columns;
int tile_rows; int tile_rows;
#if CONFIG_MAX_TILE #if CONFIG_MAX_TILE
int tile_width; int tile_width_count;
int tile_height; int tile_height_count;
int tile_widths[MAX_TILE_COLS];
int tile_heights[MAX_TILE_ROWS];
#endif #endif
#if CONFIG_DEPENDENT_HORZTILES #if CONFIG_DEPENDENT_HORZTILES
int dependent_horz_tiles; int dependent_horz_tiles;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment