diff mbox series

[FFmpeg-devel,3/3] lavc/vaapi_encode_h265: add h265 tile encoding support

Message ID 1584973479-32167-1-git-send-email-linjie.fu@intel.com
State New
Headers show
Series [FFmpeg-devel,1/3] lavc/vaapi_encode: wrap slice codes into row slice functions
Related show

Checks

Context Check Description
andriy/ffmpeg-patchwork pending
andriy/ffmpeg-patchwork success Applied patch
andriy/ffmpeg-patchwork success Configure finished
andriy/ffmpeg-patchwork success Make finished
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Fu, Linjie March 23, 2020, 2:24 p.m. UTC
Default to enable uniform_spacing_flag. Guess level by the tile
rows/cols. Supported for ICL+ platforms.

Also add documentations.

To encode with 4 rows 2 columns:
    ffmpeg ... -c:v hevc_vaapi -tile_rows 4 -tile_cols 2 ...

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 doc/encoders.texi              |  8 ++++++++
 libavcodec/vaapi_encode_h265.c | 36 +++++++++++++++++++++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

Comments

mypopy@gmail.com March 23, 2020, 2:43 p.m. UTC | #1
On Mon, Mar 23, 2020 at 10:30 PM Linjie Fu <linjie.fu@intel.com> wrote:
>
> Default to enable uniform_spacing_flag. Guess level by the tile
> rows/cols. Supported for ICL+ platforms.
>
> Also add documentations.
>
> To encode with 4 rows 2 columns:
>     ffmpeg ... -c:v hevc_vaapi -tile_rows 4 -tile_cols 2 ...
>
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
>  doc/encoders.texi              |  8 ++++++++
>  libavcodec/vaapi_encode_h265.c | 36 +++++++++++++++++++++++++++++++++++-
>  2 files changed, 43 insertions(+), 1 deletion(-)
>
> diff --git a/doc/encoders.texi b/doc/encoders.texi
> index e23b6b3..2dc5cd4 100644
> --- a/doc/encoders.texi
> +++ b/doc/encoders.texi
> @@ -3091,6 +3091,14 @@ Include HDR metadata if the input frames have it
>  messages).
>  @end table
>
> +@item tile_rows
> +Selects how many rows of tiles to encode with. For example, 4 tile rows would
> +be requested by setting the tile_rows option to 4.
> +
> +@item tile_cols
> +Selects how many columns of tiles to encode with. For example, 5 tile columns
> +would be requested by setting the tile_cols option to 5.
> +
>  @end table
>
>  @item mjpeg_vaapi
> diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
> index 97dc5a7..457e3d9 100644
> --- a/libavcodec/vaapi_encode_h265.c
> +++ b/libavcodec/vaapi_encode_h265.c
> @@ -63,6 +63,9 @@ typedef struct VAAPIEncodeH265Context {
>      int level;
>      int sei;
>
> +    int trows;
> +    int tcols;
> +
>      // Derived settings.
>      int fixed_qp_idr;
>      int fixed_qp_p;
> @@ -345,7 +348,7 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
>
>          level = ff_h265_guess_level(ptl, avctx->bit_rate,
>                                      ctx->surface_width, ctx->surface_height,
> -                                    ctx->nb_slices, 1, 1,
> +                                    ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
>                                      (ctx->b_per_p > 0) + 1);
>          if (level) {
>              av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
> @@ -558,6 +561,20 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
>
>      pps->pps_loop_filter_across_slices_enabled_flag = 1;
>
> +    if (ctx->tile_rows && ctx->tile_cols) {
> +        pps->tiles_enabled_flag         = 1;
> +        pps->uniform_spacing_flag       = 1;
> +
> +        pps->num_tile_rows_minus1       = ctx->tile_rows - 1;
> +        pps->num_tile_columns_minus1    = ctx->tile_cols - 1;
> +
> +        pps->loop_filter_across_tiles_enabled_flag = 1;
> +
> +        for (i = 0; i <= pps->num_tile_rows_minus1; i++)
> +            pps->row_height_minus1[i]   = ctx->row_height[i] - 1;
> +        for (i = 0; i <= pps->num_tile_columns_minus1; i++)
> +            pps->column_width_minus1[i] = ctx->col_width[i] - 1;
> +    }
>
>      // Fill VAAPI parameter buffers.
>
> @@ -666,6 +683,13 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
>          },
>      };
>
> +    if (pps->tiles_enabled_flag) {
> +        for (i = 0; i <= vpic->num_tile_rows_minus1; i++)
> +            vpic->row_height_minus1[i]   = pps->row_height_minus1[i];
> +        for (i = 0; i <= vpic->num_tile_columns_minus1; i++)
> +            vpic->column_width_minus1[i] = pps->column_width_minus1[i];
> +    }
> +
>      return 0;
>  }
>
> @@ -1181,6 +1205,11 @@ static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
>      if (priv->qp > 0)
>          ctx->explicit_qp = priv->qp;
>
> +    if (priv->trows && priv->tcols) {
> +        ctx->tile_rows = priv->trows;
> +        ctx->tile_cols = priv->tcols;
> +    }
> +
>      return ff_vaapi_encode_init(avctx);
>  }
>
> @@ -1257,6 +1286,11 @@ static const AVOption vaapi_encode_h265_options[] = {
>        { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
>        INT_MIN, INT_MAX, FLAGS, "sei" },
>
> +    { "tile_rows", "Number of rows for tile encoding",
> +      OFFSET(trows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> +    { "tile_cols", "Number of cols for tile encoding",
> +      OFFSET(tcols), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> +
>      { NULL },
>  };
>
> --

As my viewpoint, -tiles 3x2 (rows x cols) more naturally
Fu, Linjie March 24, 2020, 2:14 a.m. UTC | #2
> From: mypopy@gmail.com <mypopy@gmail.com>
> Sent: Monday, March 23, 2020 22:44
> To: FFmpeg development discussions and patches <ffmpeg-
> devel@ffmpeg.org>
> Cc: Fu, Linjie <linjie.fu@intel.com>
> Subject: Re: [FFmpeg-devel] [PATCH 3/3] lavc/vaapi_encode_h265: add h265
> tile encoding support
> 
> On Mon, Mar 23, 2020 at 10:30 PM Linjie Fu <linjie.fu@intel.com> wrote:
> >
> > Default to enable uniform_spacing_flag. Guess level by the tile
> > rows/cols. Supported for ICL+ platforms.
> >
> > Also add documentations.
> >
> > To encode with 4 rows 2 columns:
> >     ffmpeg ... -c:v hevc_vaapi -tile_rows 4 -tile_cols 2 ...
> >
> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> > ---
> >  doc/encoders.texi              |  8 ++++++++
> >  libavcodec/vaapi_encode_h265.c | 36
> +++++++++++++++++++++++++++++++++++-
> >  2 files changed, 43 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/encoders.texi b/doc/encoders.texi
> > index e23b6b3..2dc5cd4 100644
> > --- a/doc/encoders.texi
> > +++ b/doc/encoders.texi
> > @@ -3091,6 +3091,14 @@ Include HDR metadata if the input frames have it
> >  messages).
> >  @end table
> >
> > +@item tile_rows
> > +Selects how many rows of tiles to encode with. For example, 4 tile rows
> would
> > +be requested by setting the tile_rows option to 4.
> > +
> > +@item tile_cols
> > +Selects how many columns of tiles to encode with. For example, 5 tile
> columns
> > +would be requested by setting the tile_cols option to 5.
> > +
> >  @end table
> >
> >  @item mjpeg_vaapi
> > diff --git a/libavcodec/vaapi_encode_h265.c
> b/libavcodec/vaapi_encode_h265.c
> > index 97dc5a7..457e3d9 100644
> > --- a/libavcodec/vaapi_encode_h265.c
> > +++ b/libavcodec/vaapi_encode_h265.c
> > @@ -63,6 +63,9 @@ typedef struct VAAPIEncodeH265Context {
> >      int level;
> >      int sei;
> >
> > +    int trows;
> > +    int tcols;
> > +
> >      // Derived settings.
> >      int fixed_qp_idr;
> >      int fixed_qp_p;
> > @@ -345,7 +348,7 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> >
> >          level = ff_h265_guess_level(ptl, avctx->bit_rate,
> >                                      ctx->surface_width, ctx->surface_height,
> > -                                    ctx->nb_slices, 1, 1,
> > +                                    ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
> >                                      (ctx->b_per_p > 0) + 1);
> >          if (level) {
> >              av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
> > @@ -558,6 +561,20 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> >
> >      pps->pps_loop_filter_across_slices_enabled_flag = 1;
> >
> > +    if (ctx->tile_rows && ctx->tile_cols) {
> > +        pps->tiles_enabled_flag         = 1;
> > +        pps->uniform_spacing_flag       = 1;
> > +
> > +        pps->num_tile_rows_minus1       = ctx->tile_rows - 1;
> > +        pps->num_tile_columns_minus1    = ctx->tile_cols - 1;
> > +
> > +        pps->loop_filter_across_tiles_enabled_flag = 1;
> > +
> > +        for (i = 0; i <= pps->num_tile_rows_minus1; i++)
> > +            pps->row_height_minus1[i]   = ctx->row_height[i] - 1;
> > +        for (i = 0; i <= pps->num_tile_columns_minus1; i++)
> > +            pps->column_width_minus1[i] = ctx->col_width[i] - 1;
> > +    }
> >
> >      // Fill VAAPI parameter buffers.
> >
> > @@ -666,6 +683,13 @@ static int
> vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> >          },
> >      };
> >
> > +    if (pps->tiles_enabled_flag) {
> > +        for (i = 0; i <= vpic->num_tile_rows_minus1; i++)
> > +            vpic->row_height_minus1[i]   = pps->row_height_minus1[i];
> > +        for (i = 0; i <= vpic->num_tile_columns_minus1; i++)
> > +            vpic->column_width_minus1[i] = pps->column_width_minus1[i];
> > +    }
> > +
> >      return 0;
> >  }
> >
> > @@ -1181,6 +1205,11 @@ static av_cold int
> vaapi_encode_h265_init(AVCodecContext *avctx)
> >      if (priv->qp > 0)
> >          ctx->explicit_qp = priv->qp;
> >
> > +    if (priv->trows && priv->tcols) {
> > +        ctx->tile_rows = priv->trows;
> > +        ctx->tile_cols = priv->tcols;
> > +    }
> > +
> >      return ff_vaapi_encode_init(avctx);
> >  }
> >
> > @@ -1257,6 +1286,11 @@ static const AVOption
> vaapi_encode_h265_options[] = {
> >        { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
> >        INT_MIN, INT_MAX, FLAGS, "sei" },
> >
> > +    { "tile_rows", "Number of rows for tile encoding",
> > +      OFFSET(trows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> > +    { "tile_cols", "Number of cols for tile encoding",
> > +      OFFSET(tcols), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> > +
> >      { NULL },
> >  };
> >
> > --
> 
> As my viewpoint, -tiles 3x2 (rows x cols) more naturally

Yep, saw identical options in libaomenc[1] which support "-tiles", "- tile-columns", "- tile-rows" .

Add -tiles option as well for more natural usages:

+    { "tiles", "Tile rows x cols",
+      OFFSET(trows), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, FLAGS },

Fixed locally, thanks.

- Linjie


[1] https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/libaomenc.c#L1088
Fu, Linjie March 28, 2020, 3:01 p.m. UTC | #3
> From: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> On Behalf Of Fu,
> Linjie
> Sent: Tuesday, March 24, 2020 10:15
> To: mypopy@gmail.com; FFmpeg development discussions and patches
> <ffmpeg-devel@ffmpeg.org>
> Subject: Re: [FFmpeg-devel] [PATCH 3/3] lavc/vaapi_encode_h265: add h265
> tile encoding support
> 
> > From: mypopy@gmail.com <mypopy@gmail.com>
> > Sent: Monday, March 23, 2020 22:44
> > To: FFmpeg development discussions and patches <ffmpeg-
> > devel@ffmpeg.org>
> > Cc: Fu, Linjie <linjie.fu@intel.com>
> > Subject: Re: [FFmpeg-devel] [PATCH 3/3] lavc/vaapi_encode_h265: add
> h265
> > tile encoding support
> >
> > On Mon, Mar 23, 2020 at 10:30 PM Linjie Fu <linjie.fu@intel.com> wrote:
> > >
> > > Default to enable uniform_spacing_flag. Guess level by the tile
> > > rows/cols. Supported for ICL+ platforms.
> > >
> > > Also add documentations.
> > >
> > > To encode with 4 rows 2 columns:
> > >     ffmpeg ... -c:v hevc_vaapi -tile_rows 4 -tile_cols 2 ...
> > >
> > > Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> > > ---
> > >  doc/encoders.texi              |  8 ++++++++
> > >  libavcodec/vaapi_encode_h265.c | 36
> > +++++++++++++++++++++++++++++++++++-
> > >  2 files changed, 43 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/doc/encoders.texi b/doc/encoders.texi
> > > index e23b6b3..2dc5cd4 100644
> > > --- a/doc/encoders.texi
> > > +++ b/doc/encoders.texi
> > > @@ -3091,6 +3091,14 @@ Include HDR metadata if the input frames have
> it
> > >  messages).
> > >  @end table
> > >
> > > +@item tile_rows
> > > +Selects how many rows of tiles to encode with. For example, 4 tile rows
> > would
> > > +be requested by setting the tile_rows option to 4.
> > > +
> > > +@item tile_cols
> > > +Selects how many columns of tiles to encode with. For example, 5 tile
> > columns
> > > +would be requested by setting the tile_cols option to 5.
> > > +
> > >  @end table
> > >
> > >  @item mjpeg_vaapi
> > > diff --git a/libavcodec/vaapi_encode_h265.c
> > b/libavcodec/vaapi_encode_h265.c
> > > index 97dc5a7..457e3d9 100644
> > > --- a/libavcodec/vaapi_encode_h265.c
> > > +++ b/libavcodec/vaapi_encode_h265.c
> > > @@ -63,6 +63,9 @@ typedef struct VAAPIEncodeH265Context {
> > >      int level;
> > >      int sei;
> > >
> > > +    int trows;
> > > +    int tcols;
> > > +
> > >      // Derived settings.
> > >      int fixed_qp_idr;
> > >      int fixed_qp_p;
> > > @@ -345,7 +348,7 @@ static int
> > vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> > >
> > >          level = ff_h265_guess_level(ptl, avctx->bit_rate,
> > >                                      ctx->surface_width, ctx->surface_height,
> > > -                                    ctx->nb_slices, 1, 1,
> > > +                                    ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
> > >                                      (ctx->b_per_p > 0) + 1);
> > >          if (level) {
> > >              av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level-
> >name);
> > > @@ -558,6 +561,20 @@ static int
> > vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> > >
> > >      pps->pps_loop_filter_across_slices_enabled_flag = 1;
> > >
> > > +    if (ctx->tile_rows && ctx->tile_cols) {
> > > +        pps->tiles_enabled_flag         = 1;
> > > +        pps->uniform_spacing_flag       = 1;
> > > +
> > > +        pps->num_tile_rows_minus1       = ctx->tile_rows - 1;
> > > +        pps->num_tile_columns_minus1    = ctx->tile_cols - 1;
> > > +
> > > +        pps->loop_filter_across_tiles_enabled_flag = 1;
> > > +
> > > +        for (i = 0; i <= pps->num_tile_rows_minus1; i++)
> > > +            pps->row_height_minus1[i]   = ctx->row_height[i] - 1;
> > > +        for (i = 0; i <= pps->num_tile_columns_minus1; i++)
> > > +            pps->column_width_minus1[i] = ctx->col_width[i] - 1;
> > > +    }
> > >
> > >      // Fill VAAPI parameter buffers.
> > >
> > > @@ -666,6 +683,13 @@ static int
> > vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
> > >          },
> > >      };
> > >
> > > +    if (pps->tiles_enabled_flag) {
> > > +        for (i = 0; i <= vpic->num_tile_rows_minus1; i++)
> > > +            vpic->row_height_minus1[i]   = pps->row_height_minus1[i];
> > > +        for (i = 0; i <= vpic->num_tile_columns_minus1; i++)
> > > +            vpic->column_width_minus1[i] = pps->column_width_minus1[i];
> > > +    }
> > > +
> > >      return 0;
> > >  }
> > >
> > > @@ -1181,6 +1205,11 @@ static av_cold int
> > vaapi_encode_h265_init(AVCodecContext *avctx)
> > >      if (priv->qp > 0)
> > >          ctx->explicit_qp = priv->qp;
> > >
> > > +    if (priv->trows && priv->tcols) {
> > > +        ctx->tile_rows = priv->trows;
> > > +        ctx->tile_cols = priv->tcols;
> > > +    }
> > > +
> > >      return ff_vaapi_encode_init(avctx);
> > >  }
> > >
> > > @@ -1257,6 +1286,11 @@ static const AVOption
> > vaapi_encode_h265_options[] = {
> > >        { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
> > >        INT_MIN, INT_MAX, FLAGS, "sei" },
> > >
> > > +    { "tile_rows", "Number of rows for tile encoding",
> > > +      OFFSET(trows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> > > +    { "tile_cols", "Number of cols for tile encoding",
> > > +      OFFSET(tcols), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
> > > +
> > >      { NULL },
> > >  };
> > >
> > > --
> >
> > As my viewpoint, -tiles 3x2 (rows x cols) more naturally
> 
> Yep, saw identical options in libaomenc[1] which support "-tiles", "- tile-
> columns", "- tile-rows" .
> 
> Add -tiles option as well for more natural usages:
> 
> +    { "tiles", "Tile rows x cols",
> +      OFFSET(trows), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, FLAGS },
> 
> Fixed locally, thanks.

> https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/libaomenc.c#
> L1088
> 
Ping.

- Linjie
diff mbox series

Patch

diff --git a/doc/encoders.texi b/doc/encoders.texi
index e23b6b3..2dc5cd4 100644
--- a/doc/encoders.texi
+++ b/doc/encoders.texi
@@ -3091,6 +3091,14 @@  Include HDR metadata if the input frames have it
 messages).
 @end table
 
+@item tile_rows
+Selects how many rows of tiles to encode with. For example, 4 tile rows would
+be requested by setting the tile_rows option to 4.
+
+@item tile_cols
+Selects how many columns of tiles to encode with. For example, 5 tile columns
+would be requested by setting the tile_cols option to 5.
+
 @end table
 
 @item mjpeg_vaapi
diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c
index 97dc5a7..457e3d9 100644
--- a/libavcodec/vaapi_encode_h265.c
+++ b/libavcodec/vaapi_encode_h265.c
@@ -63,6 +63,9 @@  typedef struct VAAPIEncodeH265Context {
     int level;
     int sei;
 
+    int trows;
+    int tcols;
+
     // Derived settings.
     int fixed_qp_idr;
     int fixed_qp_p;
@@ -345,7 +348,7 @@  static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 
         level = ff_h265_guess_level(ptl, avctx->bit_rate,
                                     ctx->surface_width, ctx->surface_height,
-                                    ctx->nb_slices, 1, 1,
+                                    ctx->nb_slices, ctx->tile_rows, ctx->tile_cols,
                                     (ctx->b_per_p > 0) + 1);
         if (level) {
             av_log(avctx, AV_LOG_VERBOSE, "Using level %s.\n", level->name);
@@ -558,6 +561,20 @@  static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
 
     pps->pps_loop_filter_across_slices_enabled_flag = 1;
 
+    if (ctx->tile_rows && ctx->tile_cols) {
+        pps->tiles_enabled_flag         = 1;
+        pps->uniform_spacing_flag       = 1;
+
+        pps->num_tile_rows_minus1       = ctx->tile_rows - 1;
+        pps->num_tile_columns_minus1    = ctx->tile_cols - 1;
+
+        pps->loop_filter_across_tiles_enabled_flag = 1;
+
+        for (i = 0; i <= pps->num_tile_rows_minus1; i++)
+            pps->row_height_minus1[i]   = ctx->row_height[i] - 1;
+        for (i = 0; i <= pps->num_tile_columns_minus1; i++)
+            pps->column_width_minus1[i] = ctx->col_width[i] - 1;
+    }
 
     // Fill VAAPI parameter buffers.
 
@@ -666,6 +683,13 @@  static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx)
         },
     };
 
+    if (pps->tiles_enabled_flag) {
+        for (i = 0; i <= vpic->num_tile_rows_minus1; i++)
+            vpic->row_height_minus1[i]   = pps->row_height_minus1[i];
+        for (i = 0; i <= vpic->num_tile_columns_minus1; i++)
+            vpic->column_width_minus1[i] = pps->column_width_minus1[i];
+    }
+
     return 0;
 }
 
@@ -1181,6 +1205,11 @@  static av_cold int vaapi_encode_h265_init(AVCodecContext *avctx)
     if (priv->qp > 0)
         ctx->explicit_qp = priv->qp;
 
+    if (priv->trows && priv->tcols) {
+        ctx->tile_rows = priv->trows;
+        ctx->tile_cols = priv->tcols;
+    }
+
     return ff_vaapi_encode_init(avctx);
 }
 
@@ -1257,6 +1286,11 @@  static const AVOption vaapi_encode_h265_options[] = {
       { .i64 = SEI_MASTERING_DISPLAY | SEI_CONTENT_LIGHT_LEVEL },
       INT_MIN, INT_MAX, FLAGS, "sei" },
 
+    { "tile_rows", "Number of rows for tile encoding",
+      OFFSET(trows), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+    { "tile_cols", "Number of cols for tile encoding",
+      OFFSET(tcols), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+
     { NULL },
 };