Re: [FFmpeg-devel] [PATCH] libaomenc: Add support for tiles

2018-10-28 Thread Mark Thompson
On 27/10/18 19:58, James Almer wrote:
> On 10/22/2018 7:40 PM, Mark Thompson wrote:
>> Adds an option to specify the number of tile rows and columns, then uses
>> a uniform tiling if possible and otherwise a fixed tiling with equal-sized
>> tiles to fill the frame.
>>
>> Also adds -tile-columns and -tile-rows options to make tilings with
>> power-of-two numbers of tiles, matching the behaviour of the libvpx/VP9
>> encoder.
>> ---
>> On 03/10/18 00:50, Mark Thompson wrote:
>>> ...
>>
>> Ping.
>>
>> (Rebased following e265832c378c3f4dc372f1c0f477810f63dd60fd.)
>>
>> Thanks,
>>
>> - Mark
>>
>>
>>  libavcodec/libaomenc.c | 188 +
>>  1 file changed, 188 insertions(+)
>>
>> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
>> index 045c519f72..c5458766cb 100644
>> --- a/libavcodec/libaomenc.c
>> +++ b/libavcodec/libaomenc.c
>> @@ -34,6 +34,7 @@
>>  #include "libavutil/opt.h"
>>  #include "libavutil/pixdesc.h"
>>  
>> +#include "av1.h"
>>  #include "avcodec.h"
>>  #include "internal.h"
>>  #include "profiles.h"
>> @@ -74,6 +75,10 @@ typedef struct AOMEncoderContext {
>>  uint64_t sse[4];
>>  int have_sse; /**< true if we have pending sse[] */
>>  uint64_t frame_number;
>> +int tile_cols, tile_rows;
>> +int tile_cols_log2, tile_rows_log2;
>> +aom_superblock_size_t superblock_size;
>> +int uniform_tiles;
>>  } AOMContext;
>>  
>>  static const char *const ctlidstr[] = {
>> @@ -85,6 +90,9 @@ static const char *const ctlidstr[] = {
>>  [AV1E_SET_COLOR_PRIMARIES]  = "AV1E_SET_COLOR_PRIMARIES",
>>  [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
>>  [AV1E_SET_TRANSFER_CHARACTERISTICS] = 
>> "AV1E_SET_TRANSFER_CHARACTERISTICS",
>> +[AV1E_SET_SUPERBLOCK_SIZE]  = "AV1E_SET_SUPERBLOCK_SIZE",
>> +[AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS",
>> +[AV1E_SET_TILE_ROWS]= "AV1E_SET_TILE_ROWS",
>>  };
>>  
>>  static av_cold void log_encoder_error(AVCodecContext *avctx, const char 
>> *desc)
>> @@ -149,6 +157,10 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx,
>> width, "kf_mode:", cfg->kf_mode,
>> width, "kf_min_dist:", cfg->kf_min_dist,
>> width, "kf_max_dist:", cfg->kf_max_dist);
>> +av_log(avctx, level, "tile settings\n"
>> + "  %*s%d\n  %*s%d\n",
>> +   width, "tile_width_count:",  cfg->tile_width_count,
>> +   width, "tile_height_count:", cfg->tile_height_count);
>>  av_log(avctx, level, "\n");
>>  }
>>  
>> @@ -290,6 +302,169 @@ static void set_color_range(AVCodecContext *avctx)
>>  codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr);
>>  }
>>  
>> +static int count_uniform_tiling(int dim, int sb_size, int tiles_log2)
>> +{
>> +int sb_dim   = (dim + sb_size - 1) / sb_size;
>> +int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
>> +av_assert0(tile_dim > 0);
>> +return (sb_dim + tile_dim - 1) / tile_dim;
>> +}
>> +
>> +static int choose_tiling(AVCodecContext *avctx,
>> + struct aom_codec_enc_cfg *enccfg)
>> +{
>> +AOMContext *ctx = avctx->priv_data;
>> +int sb_128x128_possible, sb_size, sb_width, sb_height;
>> +int uniform_rows, uniform_cols;
>> +int uniform_64x64_possible, uniform_128x128_possible;
>> +int tile_size, rounding, i;
>> +
>> +if (ctx->tile_cols_log2 >= 0)
>> +ctx->tile_cols = 1 << ctx->tile_cols_log2;
>> +if (ctx->tile_rows_log2 >= 0)
>> +ctx->tile_rows = 1 << ctx->tile_rows_log2;
>> +
>> +if (ctx->tile_cols == 0) {
>> +ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) /
>> +AV1_MAX_TILE_WIDTH;
>> +if (ctx->tile_cols > 1) {
>> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
>> +   "columns to fill width.\n", ctx->tile_cols);
>> +}
>> +}
>> +av_assert0(ctx->tile_cols > 0);
>> +if (ctx->tile_rows == 0) {
>> +int max_tile_width =
>> +FFALIGN((FFALIGN(avctx->width, 128) +
>> + ctx->tile_cols - 1) / ctx->tile_cols, 128);
>> +ctx->tile_rows =
>> +(max_tile_width * FFALIGN(avctx->height, 128) +
>> + AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA;
>> +if (ctx->tile_rows > 1) {
>> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
>> +   "rows to fill area.\n", ctx->tile_rows);
>> +}
>> +}
>> +av_assert0(ctx->tile_rows > 0);
>> +
>> +if ((avctx->width  + 63) / 64 < ctx->tile_cols ||
>> +(avctx->height + 63) / 64 < ctx->tile_rows) {
>> +av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not "
>> +   "large enough to fit specified tile arrangement.\n");
>> +return AVERROR(EINVAL);
>> +}
>> +if (ctx->tile_cols > AV1_MAX_TILE_COLS ||
>> +ctx->tile_rows > AV1_MAX_TILE_ROWS) {
>> +av_log(avctx, 

Re: [FFmpeg-devel] [PATCH] libaomenc: Add support for tiles

2018-10-27 Thread James Almer
On 10/22/2018 7:40 PM, Mark Thompson wrote:
> Adds an option to specify the number of tile rows and columns, then uses
> a uniform tiling if possible and otherwise a fixed tiling with equal-sized
> tiles to fill the frame.
> 
> Also adds -tile-columns and -tile-rows options to make tilings with
> power-of-two numbers of tiles, matching the behaviour of the libvpx/VP9
> encoder.
> ---
> On 03/10/18 00:50, Mark Thompson wrote:
>> ...
> 
> Ping.
> 
> (Rebased following e265832c378c3f4dc372f1c0f477810f63dd60fd.)
> 
> Thanks,
> 
> - Mark
> 
> 
>  libavcodec/libaomenc.c | 188 +
>  1 file changed, 188 insertions(+)
> 
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index 045c519f72..c5458766cb 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -34,6 +34,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>  
> +#include "av1.h"
>  #include "avcodec.h"
>  #include "internal.h"
>  #include "profiles.h"
> @@ -74,6 +75,10 @@ typedef struct AOMEncoderContext {
>  uint64_t sse[4];
>  int have_sse; /**< true if we have pending sse[] */
>  uint64_t frame_number;
> +int tile_cols, tile_rows;
> +int tile_cols_log2, tile_rows_log2;
> +aom_superblock_size_t superblock_size;
> +int uniform_tiles;
>  } AOMContext;
>  
>  static const char *const ctlidstr[] = {
> @@ -85,6 +90,9 @@ static const char *const ctlidstr[] = {
>  [AV1E_SET_COLOR_PRIMARIES]  = "AV1E_SET_COLOR_PRIMARIES",
>  [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
>  [AV1E_SET_TRANSFER_CHARACTERISTICS] = 
> "AV1E_SET_TRANSFER_CHARACTERISTICS",
> +[AV1E_SET_SUPERBLOCK_SIZE]  = "AV1E_SET_SUPERBLOCK_SIZE",
> +[AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS",
> +[AV1E_SET_TILE_ROWS]= "AV1E_SET_TILE_ROWS",
>  };
>  
>  static av_cold void log_encoder_error(AVCodecContext *avctx, const char 
> *desc)
> @@ -149,6 +157,10 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx,
> width, "kf_mode:", cfg->kf_mode,
> width, "kf_min_dist:", cfg->kf_min_dist,
> width, "kf_max_dist:", cfg->kf_max_dist);
> +av_log(avctx, level, "tile settings\n"
> + "  %*s%d\n  %*s%d\n",
> +   width, "tile_width_count:",  cfg->tile_width_count,
> +   width, "tile_height_count:", cfg->tile_height_count);
>  av_log(avctx, level, "\n");
>  }
>  
> @@ -290,6 +302,169 @@ static void set_color_range(AVCodecContext *avctx)
>  codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr);
>  }
>  
> +static int count_uniform_tiling(int dim, int sb_size, int tiles_log2)
> +{
> +int sb_dim   = (dim + sb_size - 1) / sb_size;
> +int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
> +av_assert0(tile_dim > 0);
> +return (sb_dim + tile_dim - 1) / tile_dim;
> +}
> +
> +static int choose_tiling(AVCodecContext *avctx,
> + struct aom_codec_enc_cfg *enccfg)
> +{
> +AOMContext *ctx = avctx->priv_data;
> +int sb_128x128_possible, sb_size, sb_width, sb_height;
> +int uniform_rows, uniform_cols;
> +int uniform_64x64_possible, uniform_128x128_possible;
> +int tile_size, rounding, i;
> +
> +if (ctx->tile_cols_log2 >= 0)
> +ctx->tile_cols = 1 << ctx->tile_cols_log2;
> +if (ctx->tile_rows_log2 >= 0)
> +ctx->tile_rows = 1 << ctx->tile_rows_log2;
> +
> +if (ctx->tile_cols == 0) {
> +ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) /
> +AV1_MAX_TILE_WIDTH;
> +if (ctx->tile_cols > 1) {
> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
> +   "columns to fill width.\n", ctx->tile_cols);
> +}
> +}
> +av_assert0(ctx->tile_cols > 0);
> +if (ctx->tile_rows == 0) {
> +int max_tile_width =
> +FFALIGN((FFALIGN(avctx->width, 128) +
> + ctx->tile_cols - 1) / ctx->tile_cols, 128);
> +ctx->tile_rows =
> +(max_tile_width * FFALIGN(avctx->height, 128) +
> + AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA;
> +if (ctx->tile_rows > 1) {
> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
> +   "rows to fill area.\n", ctx->tile_rows);
> +}
> +}
> +av_assert0(ctx->tile_rows > 0);
> +
> +if ((avctx->width  + 63) / 64 < ctx->tile_cols ||
> +(avctx->height + 63) / 64 < ctx->tile_rows) {
> +av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not "
> +   "large enough to fit specified tile arrangement.\n");
> +return AVERROR(EINVAL);
> +}
> +if (ctx->tile_cols > AV1_MAX_TILE_COLS ||
> +ctx->tile_rows > AV1_MAX_TILE_ROWS) {
> +av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
> +   "not allow more than %dx%d tiles.\n",
> +   AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS);
> +

Re: [FFmpeg-devel] [PATCH] libaomenc: Add support for tiles

2018-10-26 Thread Thierry Foucu
On Mon, Oct 22, 2018 at 3:45 PM Mark Thompson  wrote:

> Adds an option to specify the number of tile rows and columns, then uses
> a uniform tiling if possible and otherwise a fixed tiling with equal-sized
> tiles to fill the frame.
>
> Also adds -tile-columns and -tile-rows options to make tilings with
> power-of-two numbers of tiles, matching the behaviour of the libvpx/VP9
> encoder.
> ---
> On 03/10/18 00:50, Mark Thompson wrote:
> > ...
>
> Ping.
>
> (Rebased following e265832c378c3f4dc372f1c0f477810f63dd60fd.)
>
> Thanks,
>
> - Mark
>
>
>  libavcodec/libaomenc.c | 188 +
>  1 file changed, 188 insertions(+)
>
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index 045c519f72..c5458766cb 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> @@ -34,6 +34,7 @@
>  #include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>
> +#include "av1.h"
>  #include "avcodec.h"
>  #include "internal.h"
>  #include "profiles.h"
> @@ -74,6 +75,10 @@ typedef struct AOMEncoderContext {
>  uint64_t sse[4];
>  int have_sse; /**< true if we have pending sse[] */
>  uint64_t frame_number;
> +int tile_cols, tile_rows;
> +int tile_cols_log2, tile_rows_log2;
> +aom_superblock_size_t superblock_size;
> +int uniform_tiles;
>  } AOMContext;
>
>  static const char *const ctlidstr[] = {
> @@ -85,6 +90,9 @@ static const char *const ctlidstr[] = {
>  [AV1E_SET_COLOR_PRIMARIES]  = "AV1E_SET_COLOR_PRIMARIES",
>  [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
>  [AV1E_SET_TRANSFER_CHARACTERISTICS] =
> "AV1E_SET_TRANSFER_CHARACTERISTICS",
> +[AV1E_SET_SUPERBLOCK_SIZE]  = "AV1E_SET_SUPERBLOCK_SIZE",
> +[AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS",
> +[AV1E_SET_TILE_ROWS]= "AV1E_SET_TILE_ROWS",
>  };
>
>  static av_cold void log_encoder_error(AVCodecContext *avctx, const char
> *desc)
> @@ -149,6 +157,10 @@ static av_cold void dump_enc_cfg(AVCodecContext
> *avctx,
> width, "kf_mode:", cfg->kf_mode,
> width, "kf_min_dist:", cfg->kf_min_dist,
> width, "kf_max_dist:", cfg->kf_max_dist);
> +av_log(avctx, level, "tile settings\n"
> + "  %*s%d\n  %*s%d\n",
> +   width, "tile_width_count:",  cfg->tile_width_count,
> +   width, "tile_height_count:", cfg->tile_height_count);
>  av_log(avctx, level, "\n");
>  }
>
> @@ -290,6 +302,169 @@ static void set_color_range(AVCodecContext *avctx)
>  codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr);
>  }
>
> +static int count_uniform_tiling(int dim, int sb_size, int tiles_log2)
> +{
> +int sb_dim   = (dim + sb_size - 1) / sb_size;
> +int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
> +av_assert0(tile_dim > 0);
> +return (sb_dim + tile_dim - 1) / tile_dim;
> +}
> +
> +static int choose_tiling(AVCodecContext *avctx,
> + struct aom_codec_enc_cfg *enccfg)
> +{
> +AOMContext *ctx = avctx->priv_data;
> +int sb_128x128_possible, sb_size, sb_width, sb_height;
> +int uniform_rows, uniform_cols;
> +int uniform_64x64_possible, uniform_128x128_possible;
> +int tile_size, rounding, i;
> +
> +if (ctx->tile_cols_log2 >= 0)
> +ctx->tile_cols = 1 << ctx->tile_cols_log2;
> +if (ctx->tile_rows_log2 >= 0)
> +ctx->tile_rows = 1 << ctx->tile_rows_log2;
> +
> +if (ctx->tile_cols == 0) {
> +ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) /
> +AV1_MAX_TILE_WIDTH;
> +if (ctx->tile_cols > 1) {
> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
> +   "columns to fill width.\n", ctx->tile_cols);
> +}
> +}
> +av_assert0(ctx->tile_cols > 0);
> +if (ctx->tile_rows == 0) {
> +int max_tile_width =
> +FFALIGN((FFALIGN(avctx->width, 128) +
> + ctx->tile_cols - 1) / ctx->tile_cols, 128);
> +ctx->tile_rows =
> +(max_tile_width * FFALIGN(avctx->height, 128) +
> + AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA;
> +if (ctx->tile_rows > 1) {
> +av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
> +   "rows to fill area.\n", ctx->tile_rows);
> +}
> +}
> +av_assert0(ctx->tile_rows > 0);
> +
> +if ((avctx->width  + 63) / 64 < ctx->tile_cols ||
> +(avctx->height + 63) / 64 < ctx->tile_rows) {
> +av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not "
> +   "large enough to fit specified tile arrangement.\n");
> +return AVERROR(EINVAL);
> +}
> +if (ctx->tile_cols > AV1_MAX_TILE_COLS ||
> +ctx->tile_rows > AV1_MAX_TILE_ROWS) {
> +av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
> +   "not allow more than %dx%d tiles.\n",
> +   AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS);
> +return 

[FFmpeg-devel] [PATCH] libaomenc: Add support for tiles

2018-10-22 Thread Mark Thompson
Adds an option to specify the number of tile rows and columns, then uses
a uniform tiling if possible and otherwise a fixed tiling with equal-sized
tiles to fill the frame.

Also adds -tile-columns and -tile-rows options to make tilings with
power-of-two numbers of tiles, matching the behaviour of the libvpx/VP9
encoder.
---
On 03/10/18 00:50, Mark Thompson wrote:
> ...

Ping.

(Rebased following e265832c378c3f4dc372f1c0f477810f63dd60fd.)

Thanks,

- Mark


 libavcodec/libaomenc.c | 188 +
 1 file changed, 188 insertions(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 045c519f72..c5458766cb 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -34,6 +34,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
+#include "av1.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "profiles.h"
@@ -74,6 +75,10 @@ typedef struct AOMEncoderContext {
 uint64_t sse[4];
 int have_sse; /**< true if we have pending sse[] */
 uint64_t frame_number;
+int tile_cols, tile_rows;
+int tile_cols_log2, tile_rows_log2;
+aom_superblock_size_t superblock_size;
+int uniform_tiles;
 } AOMContext;
 
 static const char *const ctlidstr[] = {
@@ -85,6 +90,9 @@ static const char *const ctlidstr[] = {
 [AV1E_SET_COLOR_PRIMARIES]  = "AV1E_SET_COLOR_PRIMARIES",
 [AV1E_SET_MATRIX_COEFFICIENTS] = "AV1E_SET_MATRIX_COEFFICIENTS",
 [AV1E_SET_TRANSFER_CHARACTERISTICS] = "AV1E_SET_TRANSFER_CHARACTERISTICS",
+[AV1E_SET_SUPERBLOCK_SIZE]  = "AV1E_SET_SUPERBLOCK_SIZE",
+[AV1E_SET_TILE_COLUMNS] = "AV1E_SET_TILE_COLUMNS",
+[AV1E_SET_TILE_ROWS]= "AV1E_SET_TILE_ROWS",
 };
 
 static av_cold void log_encoder_error(AVCodecContext *avctx, const char *desc)
@@ -149,6 +157,10 @@ static av_cold void dump_enc_cfg(AVCodecContext *avctx,
width, "kf_mode:", cfg->kf_mode,
width, "kf_min_dist:", cfg->kf_min_dist,
width, "kf_max_dist:", cfg->kf_max_dist);
+av_log(avctx, level, "tile settings\n"
+ "  %*s%d\n  %*s%d\n",
+   width, "tile_width_count:",  cfg->tile_width_count,
+   width, "tile_height_count:", cfg->tile_height_count);
 av_log(avctx, level, "\n");
 }
 
@@ -290,6 +302,169 @@ static void set_color_range(AVCodecContext *avctx)
 codecctl_int(avctx, AV1E_SET_COLOR_RANGE, aom_cr);
 }
 
+static int count_uniform_tiling(int dim, int sb_size, int tiles_log2)
+{
+int sb_dim   = (dim + sb_size - 1) / sb_size;
+int tile_dim = (sb_dim + (1 << tiles_log2) - 1) >> tiles_log2;
+av_assert0(tile_dim > 0);
+return (sb_dim + tile_dim - 1) / tile_dim;
+}
+
+static int choose_tiling(AVCodecContext *avctx,
+ struct aom_codec_enc_cfg *enccfg)
+{
+AOMContext *ctx = avctx->priv_data;
+int sb_128x128_possible, sb_size, sb_width, sb_height;
+int uniform_rows, uniform_cols;
+int uniform_64x64_possible, uniform_128x128_possible;
+int tile_size, rounding, i;
+
+if (ctx->tile_cols_log2 >= 0)
+ctx->tile_cols = 1 << ctx->tile_cols_log2;
+if (ctx->tile_rows_log2 >= 0)
+ctx->tile_rows = 1 << ctx->tile_rows_log2;
+
+if (ctx->tile_cols == 0) {
+ctx->tile_cols = (avctx->width + AV1_MAX_TILE_WIDTH - 1) /
+AV1_MAX_TILE_WIDTH;
+if (ctx->tile_cols > 1) {
+av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
+   "columns to fill width.\n", ctx->tile_cols);
+}
+}
+av_assert0(ctx->tile_cols > 0);
+if (ctx->tile_rows == 0) {
+int max_tile_width =
+FFALIGN((FFALIGN(avctx->width, 128) +
+ ctx->tile_cols - 1) / ctx->tile_cols, 128);
+ctx->tile_rows =
+(max_tile_width * FFALIGN(avctx->height, 128) +
+ AV1_MAX_TILE_AREA - 1) / AV1_MAX_TILE_AREA;
+if (ctx->tile_rows > 1) {
+av_log(avctx, AV_LOG_DEBUG, "Automatically using %d tile "
+   "rows to fill area.\n", ctx->tile_rows);
+}
+}
+av_assert0(ctx->tile_rows > 0);
+
+if ((avctx->width  + 63) / 64 < ctx->tile_cols ||
+(avctx->height + 63) / 64 < ctx->tile_rows) {
+av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: frame not "
+   "large enough to fit specified tile arrangement.\n");
+return AVERROR(EINVAL);
+}
+if (ctx->tile_cols > AV1_MAX_TILE_COLS ||
+ctx->tile_rows > AV1_MAX_TILE_ROWS) {
+av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
+   "not allow more than %dx%d tiles.\n",
+   AV1_MAX_TILE_COLS, AV1_MAX_TILE_ROWS);
+return AVERROR(EINVAL);
+}
+if (avctx->width / ctx->tile_cols > AV1_MAX_TILE_WIDTH) {
+av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: AV1 does "
+   "not allow tiles of width greater than %d.\n",
+   AV1_MAX_TILE_WIDTH);
+return AVERROR(EINVAL);
+}
+

[FFmpeg-devel] [PATCH] libaomenc: Add support for tiles

2018-10-02 Thread Mark Thompson
Adds an option to specify the number of tile rows and columns, then uses
a uniform tiling if possible and otherwise a fixed tiling with equal-sized
tiles to fill the frame.

Also adds -tile-columns and -tile-rows options to make tilings with
power-of-two numbers of tiles, matching the behaviour of the libvpx/VP9
encoder.
---
On 23/09/18 23:55, Mark Thompson wrote:
> On 19/09/18 00:15, James Almer wrote:
>> On 9/18/2018 7:55 PM, Mark Thompson wrote:
>>> On 18/09/18 01:12, James Almer wrote:
 On 9/17/2018 8:47 PM, Mark Thompson wrote:
> Adds an option to specify the number of tile rows and columns, then uses
> equal-sized tiles to fill the frame.
> ---
>  libavcodec/libaomenc.c | 54 ++
>  1 file changed, 54 insertions(+)
>
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index 6a79d9b873..3ccff0e0fb 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> ...
> @@ -742,6 +795,7 @@ static const AVOption options[] = {
>  { "static-thresh","A change threshold on blocks below which they 
> will be skipped by the encoder", OFFSET(static_thresh), AV_OPT_TYPE_INT, 
> { .i64 = 0 }, 0, INT_MAX, VE },
>  { "drop-threshold",   "Frame drop threshold", offsetof(AOMContext, 
> drop_threshold), AV_OPT_TYPE_INT, {.i64 = 0 }, INT_MIN, INT_MAX, VE },
>  { "noise-sensitivity", "Noise sensitivity", 
> OFFSET(noise_sensitivity), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 4, VE},
> +{ "tiles","Tile rows x columns", OFFSET(tile_cols), 
> AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, VE },

 Using separate tile-columns and tile-rows AV_OPT_TYPE_INT options would
 be more consistent with the libvpx wrapper, which already has them
 called like that and also shares a lot of other option names with the
 libaom.
>>>
>>> The options on libvpx-vp9 are actually log2 of the value, so "-tile-rows 3 
>>> -tile-columns 2" gives you 8x4 tiles.  (VP9 requires that the number of 
>>> tiles in each dimension is a power of two, while AV1 lets you set arbitrary 
>>> sizes.)
>>>
>>> I don't really mind how this works - I just thought the IMAGE_SIZE method 
>>> looked nicer.  What do you prefer?
>>
>> I usually prefer consistency in options for similar modules, but the
>> equivalent of the VP9 options would be to set the AV1E_SET_TILE_* codec
>> control IDs instead of what you're doing here, so your IMAGE_SIZE method
>> is fine.
>>
>> There's for that matter a conflicting patch called "lavc/libaomenc: Add
>> -tile-columns/-tile-rows" by Kagami Hiiragi that sets the aforementioned
>> codec control IDs with the same option names as the VP9 ones. Maybe both
>> patches can be applied, and have the encoder abort if they are used at
>> the same time? Otherwise apply yours alone since it allows arbitrary sizes.
> 
> I think having both would make sense - the two different options are 
> reflecting the different values of uniform_tile_spacing_flag.  The explicit 
> sizing can get the same result with the flag off as it being on, but will 
> require more bits in every frame header to do so.
> 
> On matching behaviour with libvpx, I don't think tile_cols/rows_log2 in VP9 
> and AV1 (with uniform_tile_spacing_flag = 1) actually do have the same effect 
> - VP9 ensures that you get exactly 2^tile_cols_log2 tile columns, while for 
> AV1 it's an upper bound and depends on the width.  For example, given a width 
> of 576 (as 9 64x64 superblocks) and tile_cols_log2 = 2, VP9 looks like it 
> gives you { 2, 2, 2, 3 } while AV1 will give you { 3, 3, 3 } as the tile 
> column widths.  That probably wants to be mentioned in the documentation, and 
> maybe merits the options not matching precisely.
> 
> So, I'll look into supporting both cases in some consistent way.

Here we go; hopefully this covers all of the cases.  I went for making the 
options match precisely for the power-of-two values in VP9 - we can determine 
what arrangements a uniform tiling will produce and decide from that whether to 
use one or not.

- Mark


 libavcodec/libaomenc.c | 189 +
 1 file changed, 189 insertions(+)

diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
index 6a79d9b873..50abc6a5db 100644
--- a/libavcodec/libaomenc.c
+++ b/libavcodec/libaomenc.c
@@ -34,6 +34,7 @@
 #include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
+#include "av1.h"
 #include "avcodec.h"
 #include "internal.h"
 #include "profiles.h"
@@ -68,6 +69,11 @@ typedef struct AOMEncoderContext {
 int static_thresh;
 int drop_threshold;
 int noise_sensitivity;
+int tile_cols, tile_rows;
+int tile_cols_log2, tile_rows_log2;
+
+aom_superblock_size_t superblock_size;
+int uniform_tiles;
 } AOMContext;
 
 static const char *const ctlidstr[] = {
@@ -79,6 +85,9 @@ static const char *const ctlidstr[] = {
 [AV1E_SET_COLOR_PRIMARIES]  =