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

Mark Thompson sw at jkqxz.net
Mon Sep 10 01:22:35 EEST 2018


On 09/09/18 23:08, Mark Thompson wrote:
> Adds an option to specify the number of tile rows and columns, then uses
> equal-sized tiles to fill the frame.
> ---
> Useful for testing to make arbitrary arrangements of tiles, though the requirement to set the superblock size for the whole stream at the top level rather than letting it be set dynamically is slightly unfortunate.
> 
> The rounding error is placed at the left/top here, it might be better to place it around the sides instead?  (The most important detail is likely to be in the centre of the frame, so make the tiles there smaller?  I'm not sure whether this argument is actually valid, though.)
> 
> 
>  libavcodec/libaomenc.c | 55 ++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/libavcodec/libaomenc.c b/libavcodec/libaomenc.c
> index 9431179886..0b4fa71fc7 100644
> --- a/libavcodec/libaomenc.c
> +++ b/libavcodec/libaomenc.c
> ...
> @@ -431,6 +438,51 @@ static av_cold int aom_init(AVCodecContext *avctx,
>  
>      enccfg.g_error_resilient = ctx->error_resilient;
>  
> +    if (ctx->tile_cols && ctx->tile_rows) {
> +        int sb_size, sb_width, sb_height;
> +        int cols_per_tile, cols_step, rows_per_tile, rows_step, i;
> +
> +        if (avctx->width / ctx->tile_cols < 128 ||
> +            avctx->width / ctx->tile_rows < 128) {

avctx->height for the second test, of course.

There could be some rounding here too, though I'm not sure what the 128x128 vs. 64x64 tradeoff actually involves - if the frame is very small do we want the largest superblock size?

> +            // User has requested more tiles than would fit with 128x128
> +            // superblocks, so assume they want 64x64.
> +            sb_size = 64;
> +            superblock_size = AOM_SUPERBLOCK_SIZE_64X64;
> +        } else {
> +            sb_size = 128;
> +            superblock_size = AOM_SUPERBLOCK_SIZE_128X128;
> +        }
> +
> +        if (avctx->width  / ctx->tile_cols < sb_size ||
> +            avctx->height / ctx->tile_rows < sb_size) {

This should probably be rounded with the test the other way:

+        if ((avctx->width  + sb_size - 1) / sb_size < ctx->tile_cols ||
+            (avctx->height + sb_size - 1) / sb_size < ctx->tile_rows) {

> +            av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: tiles must be "
> +                   "at least one superblock wide and high.\n");
> +            return AVERROR(EINVAL);
> +        }
> +        if (ctx->tile_cols > MAX_TILE_WIDTHS ||
> +            ctx->tile_rows > MAX_TILE_HEIGHTS) {
> +            av_log(avctx, AV_LOG_ERROR, "Invalid tile sizing: at most %dx%d "
> +                   "tiles allowed.\n", MAX_TILE_WIDTHS, MAX_TILE_HEIGHTS);
> +            return AVERROR(EINVAL);
> +        }
> +
> +        enccfg.tile_width_count  = ctx->tile_cols;
> +        enccfg.tile_height_count = ctx->tile_rows;
> +
> +        sb_width   = (avctx->width  + sb_size - 1) / sb_size;
> +        sb_height  = (avctx->height + sb_size - 1) / sb_size;
> +
> +        cols_per_tile = sb_width / ctx->tile_cols;
> +        cols_step     = sb_width % ctx->tile_cols;
> +        for (i = 0; i < ctx->tile_cols; i++)
> +            enccfg.tile_widths[i] = cols_per_tile + (i < cols_step);
> +
> +        rows_per_tile = sb_height / ctx->tile_rows;
> +        rows_step     = sb_height % ctx->tile_rows;
> +        for (i = 0; i < ctx->tile_rows; i++)
> +            enccfg.tile_heights[i] = rows_per_tile + (i < rows_step);
> +    }
> ...


More information about the ffmpeg-devel mailing list