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 {
* implies a large-scale tile coding.
*/
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 */
/*!\brief Initialize an encoder instance
......
......@@ -492,26 +492,6 @@ enum aome_enc_control_id {
*/
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.
*
* In encoding and decoding, AV1 allows enabling dependent horizontal tile
......
......@@ -414,9 +414,9 @@ static const arg_def_t tile_rows =
"Number of tile rows to use, log2 (set to 0 while threads > 1)");
#if CONFIG_MAX_TILE
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 =
ARG_DEF(NULL, "tile-height", 1, "Height of each tile");
ARG_DEF(NULL, "tile-height", 1, "Tile heights (command separated)");
#endif
#if CONFIG_DEPENDENT_HORZTILES
static const arg_def_t tile_dependent_rows =
......@@ -553,10 +553,6 @@ static const arg_def_t *av1_args[] = { &cpu_used_av1,
#endif // CONFIG_EXT_TILE
&tile_cols,
&tile_rows,
#if CONFIG_MAX_TILE
&tile_width,
&tile_height,
#endif
#if CONFIG_DEPENDENT_HORZTILES
&tile_dependent_rows,
#endif
......@@ -614,10 +610,6 @@ static const int av1_arg_ctrl_map[] = { AOME_SET_CPUUSED,
#endif // CONFIG_EXT_TILE
AV1E_SET_TILE_COLUMNS,
AV1E_SET_TILE_ROWS,
#if CONFIG_MAX_TILE
AV1E_SET_TILE_WIDTH,
AV1E_SET_TILE_HEIGHT,
#endif
#if CONFIG_DEPENDENT_HORZTILES
AV1E_SET_TILE_DEPENDENT_ROWS,
#endif
......@@ -1119,6 +1111,14 @@ static int parse_stream_params(struct AvxEncoderConfig *global,
config->cfg.kf_max_dist = arg_parse_uint(&arg);
} else if (arg_match(&arg, &kf_disabled, argi)) {
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 {
int i, match = 0;
for (i = 0; ctrl_args[i]; i++) {
......
......@@ -210,3 +210,28 @@ int arg_parse_enum_or_int(const struct arg *arg) {
if (arg->def->enums) return arg_parse_enum(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);
struct aom_rational arg_parse_rational(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_list(const struct arg *arg, int *list, int n);
#ifdef __cplusplus
} // extern "C"
#endif
......
......@@ -36,10 +36,6 @@ struct av1_extracfg {
unsigned int static_thresh;
unsigned int tile_columns; // log2 number of tile columns
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
unsigned int dependent_horz_tiles;
#endif
......@@ -105,10 +101,6 @@ static struct av1_extracfg default_extra_cfg = {
0, // static_thresh
0, // tile_columns
0, // tile_rows
#if CONFIG_MAX_TILE
0, // tile_width
0, // tile_height
#endif
#if CONFIG_DEPENDENT_HORZTILES
0, // Dependent Horizontal tiles
#endif
......@@ -316,7 +308,6 @@ static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
#if CONFIG_MAX_TILE
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 6);
RANGE_CHECK_HI(extra_cfg, tile_width, MAX_TILE_WIDTH_SB);
#else // CONFIG_MAX_TILE
RANGE_CHECK_HI(extra_cfg, tile_columns, 6);
RANGE_CHECK_HI(extra_cfg, tile_rows, 2);
......@@ -639,8 +630,14 @@ static aom_codec_err_t set_encoder_config(
#endif // CONFIG_EXT_TILE
#if CONFIG_MAX_TILE
oxcf->tile_width = extra_cfg->tile_width;
oxcf->tile_height = extra_cfg->tile_height;
oxcf->tile_width_count = AOMMIN(cfg->tile_width_count, MAX_TILE_COLS);
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
#if CONFIG_DEPENDENT_HORZTILES
oxcf->dependent_horz_tiles =
......@@ -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);
}
#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
static aom_codec_err_t ctrl_set_tile_dependent_rows(aom_codec_alg_priv_t *ctx,
va_list args) {
......@@ -1582,10 +1564,6 @@ static aom_codec_ctrl_fn_map_t encoder_ctrl_maps[] = {
{ AOME_SET_STATIC_THRESHOLD, ctrl_set_static_thresh },
{ AV1E_SET_TILE_COLUMNS, ctrl_set_tile_columns },
{ 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
{ AV1E_SET_TILE_DEPENDENT_ROWS, ctrl_set_tile_dependent_rows },
#endif
......@@ -1701,6 +1679,10 @@ static aom_codec_enc_cfg_map_t encoder_usage_cfg_map[] = {
0, // kf_min_dist
9999, // kf_max_dist
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) {
av1_get_tile_limits(cm);
// 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->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);
} else {
int mi_cols = ALIGN_POWER_OF_TWO(cm->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;
for (i = 0, start_sb = 0; start_sb < sb_cols && i < MAX_TILE_COLS; i++) {
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_col_start_sb[i] = sb_cols;
......@@ -952,10 +954,12 @@ static void set_tile_info_max_tile(AV1_COMP *cpi) {
} else {
int mi_rows = ALIGN_POWER_OF_TWO(cm->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++) {
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_row_start_sb[i] = sb_rows;
......
......@@ -266,8 +266,10 @@ typedef struct AV1EncoderConfig {
int tile_columns;
int tile_rows;
#if CONFIG_MAX_TILE
int tile_width;
int tile_height;
int tile_width_count;
int tile_height_count;
int tile_widths[MAX_TILE_COLS];
int tile_heights[MAX_TILE_ROWS];
#endif
#if CONFIG_DEPENDENT_HORZTILES
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