[FFmpeg-devel] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver

Submitted by Zachary Zhou on Oct. 23, 2018, 7:52 a.m.

Details

Message ID 20181023075240.2358-1-zachary.zhou@intel.com
State New
Headers show

Commit Message

Zachary Zhou Oct. 23, 2018, 7:52 a.m.
It supports clockwise rotation by 0/90/180/270 degrees defined in
va/va_vpp.h, tested following command line on SKL platform

ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128
-hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"
-c:v h264_vaapi output.h264
---
 libavfilter/Makefile        |   1 +
 libavfilter/allfilters.c    |   1 +
 libavfilter/vaapi_vpp.h     |   1 +
 libavfilter/vf_misc_vaapi.c | 122 ++++++++++++++++++++++++++++++++++++
 4 files changed, 125 insertions(+)

Comments

Moritz Barsnick Oct. 23, 2018, 8:55 a.m.
On Tue, Oct 23, 2018 at 15:52:40 +0800, Zachary Zhou wrote:
> It supports clockwise rotation by 0/90/180/270 degrees defined in
> va/va_vpp.h, tested following command line on SKL platform

Since these angles of rotation are called "transpose" in ffmpeg's other
filters (transpose, transpose_npp), shouldn't that be the name chosen
for this functionality?

It could then also use similar options.

Just wondering.

The filter(s) could also use some documentation (doc/filters.texi), but
the existing vaapi ones don't have any either, so *sigh*.

Cheers,
Moritz
Zhong Li Oct. 23, 2018, 9:52 a.m.
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Zachary Zhou

> Sent: Tuesday, October 23, 2018 3:53 PM

> To: ffmpeg-devel@ffmpeg.org

> Cc: Zhou, Zachary <zachary.zhou@intel.com>

> Subject: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation

> feature via call Intel iHD driver

> 

> It supports clockwise rotation by 0/90/180/270 degrees defined in

> va/va_vpp.h, tested following command line on SKL platform

> 

> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128

> -hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"

> -c:v h264_vaapi output.h264

> ---

>  libavfilter/Makefile        |   1 +

>  libavfilter/allfilters.c    |   1 +

>  libavfilter/vaapi_vpp.h     |   1 +

>  libavfilter/vf_misc_vaapi.c | 122

> ++++++++++++++++++++++++++++++++++++

>  4 files changed, 125 insertions(+)

> 

> diff --git a/libavfilter/Makefile b/libavfilter/Makefile index

> 108a2f87d7..81afc100dc 100644

> --- a/libavfilter/Makefile

> +++ b/libavfilter/Makefile

> @@ -349,6 +349,7 @@ OBJS-$(CONFIG_SETRANGE_FILTER)

> += vf_setparams.o

>  OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o

>  OBJS-$(CONFIG_SETTB_FILTER)                  += settb.o

>  OBJS-$(CONFIG_SHARPNESS_VAAPI_FILTER)        += vf_misc_vaapi.o

> vaapi_vpp.o

> +OBJS-$(CONFIG_ROTATION_VAAPI_FILTER)         += vf_misc_vaapi.o

> vaapi_vpp.o

>  OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o

>  OBJS-$(CONFIG_SHOWPALETTE_FILTER)            +=

> vf_showpalette.o

>  OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)          +=

> vf_shuffleframes.o

> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index

> 557590850b..4b90a7f440 100644

> --- a/libavfilter/allfilters.c

> +++ b/libavfilter/allfilters.c

> @@ -333,6 +333,7 @@ extern AVFilter ff_vf_setrange;  extern AVFilter

> ff_vf_setsar;  extern AVFilter ff_vf_settb;  extern AVFilter

> ff_vf_sharpness_vaapi;

> +extern AVFilter ff_vf_rotation_vaapi;

>  extern AVFilter ff_vf_showinfo;

>  extern AVFilter ff_vf_showpalette;

>  extern AVFilter ff_vf_shuffleframes;

> diff --git a/libavfilter/vaapi_vpp.h b/libavfilter/vaapi_vpp.h index

> 0bc31018d4..cfe19b689f 100644

> --- a/libavfilter/vaapi_vpp.h

> +++ b/libavfilter/vaapi_vpp.h

> @@ -44,6 +44,7 @@ typedef struct VAAPIVPPContext {

>      int output_width;   // computed width

>      int output_height;  // computed height

> 

> +    int rotation_state;

>      VABufferID         filter_buffers[VAProcFilterCount];

>      int                nb_filter_buffers;

> 

> diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c index

> 30b808a993..e5d354e3dc 100644

> --- a/libavfilter/vf_misc_vaapi.c

> +++ b/libavfilter/vf_misc_vaapi.c

> @@ -37,6 +37,18 @@

>  #define SHARPNESS_MAX          64

>  #define SHARPNESS_DEFAULT      44

> 

> +// Rotation angle values

> +enum RotationAngle {

> +    ROTATION_0   = 0,

> +    ROTATION_90  = 90,

> +    ROTATION_180 = 180,

> +    ROTATION_270 = 270,

> +

> +    ROTATION_MIN     = ROTATION_0,

> +    ROTATION_MAX     = ROTATION_270,

> +    ROTATION_DEFAULT = ROTATION_0,

> +};

> +

>  typedef struct DenoiseVAAPIContext {

>      VAAPIVPPContext vpp_ctx; // must be the first field

> 

> @@ -49,6 +61,12 @@ typedef struct SharpnessVAAPIContext {

>      int sharpness;       // enable sharpness.

>  } SharpnessVAAPIContext;

> 

> +typedef struct RotationVAAPIContext {

> +    VAAPIVPPContext vpp_ctx; // must be the first field

> +

> +    int rotation;        // enable rotation.


Looks like it means rotation degree, not a flag to enable/disable rotation. 
So the comment here may be not precise.

> +} RotationVAAPIContext;

> +

>  static float map(int x, int in_min, int in_max, float out_min, float out_max)

> {

>      double slope, output;

> @@ -123,6 +141,64 @@ static int

> sharpness_vaapi_build_filter_params(AVFilterContext *avctx)

>      return 0;

>  }

> 

> +static int rotation_vaapi_build_filter_params(AVFilterContext *avctx) {

> +    VAAPIVPPContext *vpp_ctx  = avctx->priv;

> +    RotationVAAPIContext *ctx = avctx->priv;

> +

> +    VAStatus vas;

> +    int support_flag;

> +

> +    VAProcPipelineCaps pipeline_caps;

> +

> +    memset(&pipeline_caps, 0, sizeof(pipeline_caps));

> +    vas = vaQueryVideoProcPipelineCaps(vpp_ctx->hwctx->display,

> +                                       vpp_ctx->va_context,

> +                                       NULL, 0,

> +                                       &pipeline_caps);

> +    if (vas != VA_STATUS_SUCCESS) {

> +        av_log(avctx, AV_LOG_ERROR, "Failed to query pipeline "

> +               "caps: %d (%s).\n", vas, vaErrorStr(vas));

> +        return AVERROR(EIO);

> +    }

> +

> +    if (!pipeline_caps.rotation_flags) {

> +        av_log(avctx, AV_LOG_ERROR, "VAAPI driver doesn't support

> rotation\n");

> +        return AVERROR(EINVAL);

> +    }

> +

> +    switch (ctx->rotation) {

> +    case ROTATION_0:

> +        vpp_ctx->rotation_state = VA_ROTATION_NONE;

> +        break;

> +    case ROTATION_90:

> +        vpp_ctx->rotation_state = VA_ROTATION_90;

> +        break;

> +    case ROTATION_180:

> +        vpp_ctx->rotation_state = VA_ROTATION_180;

> +        break;

> +    case ROTATION_270:

> +        vpp_ctx->rotation_state = VA_ROTATION_270;

> +        break;

> +    default:

> +        av_log(avctx, AV_LOG_ERROR, "Failed to set rotation_state

> to %d. "

> +               "Clockwise %d, %d, %d and %d are only supported\n",

> +               ctx->rotation,

> +               ROTATION_0, ROTATION_90, ROTATION_180,

> ROTATION_270);

> +        return AVERROR(EINVAL);

> +    }

> +

> +    support_flag = pipeline_caps.rotation_flags &

> +                   (1 << vpp_ctx->rotation_state);

> +    if (!support_flag) {

> +        av_log(avctx, AV_LOG_ERROR, "VAAPI driver doesn't

> support %d\n",

> +               ctx->rotation);

> +        return AVERROR(EINVAL);

> +    }

> +

> +    return 0;

> +}

> +

>  static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame

> *input_frame)  {

>      AVFilterContext *avctx   = inlink->dst;

> @@ -164,6 +240,19 @@ static int misc_vaapi_filter_frame(AVFilterLink

> *inlink, AVFrame *input_frame)

>          .height = input_frame->height,

>      };

> 

> +    switch (vpp_ctx->rotation_state) {

> +    case VA_ROTATION_NONE:


Should be this case by-passed? I guess can bring a little performance benefit.

> +    case VA_ROTATION_90:

> +    case VA_ROTATION_180:

> +    case VA_ROTATION_270:

> +        params.rotation_state = vpp_ctx->rotation_state;

> +        break;

> +    default:

> +        av_log(avctx, AV_LOG_ERROR, "VAAPI doesn't support %d\n",

> +               vpp_ctx->rotation_state);

> +        goto fail;

> +    }

> +

>      if (vpp_ctx->nb_filter_buffers) {

>          params.filters     = &vpp_ctx->filter_buffers[0];

>          params.num_filters = vpp_ctx->nb_filter_buffers; @@ -225,6

> +314,18 @@ static av_cold int sharpness_vaapi_init(AVFilterContext *avctx)

>      return 0;

>  }

> 

> +static av_cold int rotation_vaapi_init(AVFilterContext *avctx) {

> +    VAAPIVPPContext *vpp_ctx = avctx->priv;

> +

> +    ff_vaapi_vpp_ctx_init(avctx);

> +    vpp_ctx->pipeline_uninit     = ff_vaapi_vpp_pipeline_uninit;

> +    vpp_ctx->build_filter_params = rotation_vaapi_build_filter_params;

> +    vpp_ctx->output_format       = AV_PIX_FMT_NONE;

> +

> +    return 0;

> +}

> +

>  #define DOFFSET(x) offsetof(DenoiseVAAPIContext, x)  #define FLAGS

> (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)  static

> const AVOption denoise_vaapi_options[] = { @@ -240,8 +341,16 @@ static

> const AVOption sharpness_vaapi_options[] = {

>      { NULL },

>  };

> 

> +#define ROFFSET(x) offsetof(RotationVAAPIContext, x) static const

> +AVOption rotation_vaapi_options[] = {

> +    { "angle", "clockwise rotation angle 0/90/180/270 are only

> supported",


Should be better if sub-options can be added, just like cclock_flip option in transpose_options.

> +      ROFFSET(rotation), AV_OPT_TYPE_INT, { .i64 =

> ROTATION_DEFAULT }, ROTATION_MIN, ROTATION_MAX, .flags = FLAGS },

> +    { NULL },

> +};

> +

>  AVFILTER_DEFINE_CLASS(denoise_vaapi);

>  AVFILTER_DEFINE_CLASS(sharpness_vaapi);

> +AVFILTER_DEFINE_CLASS(rotation_vaapi);

> 

>  static const AVFilterPad misc_vaapi_inputs[] = {

>      {

> @@ -287,3 +396,16 @@ AVFilter ff_vf_sharpness_vaapi = {

>      .priv_class    = &sharpness_vaapi_class,

>      .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,  };

> +

> +AVFilter ff_vf_rotation_vaapi = {

> +    .name          = "rotation_vaapi",

> +    .description   = NULL_IF_CONFIG_SMALL("VAAPI VPP for rotation"),

> +    .priv_size     = sizeof(RotationVAAPIContext),

> +    .init          = &rotation_vaapi_init,

> +    .uninit        = &ff_vaapi_vpp_ctx_uninit,

> +    .query_formats = &ff_vaapi_vpp_query_formats,

> +    .inputs        = misc_vaapi_inputs,

> +    .outputs       = misc_vaapi_outputs,

> +    .priv_class    = &rotation_vaapi_class,

> +    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, };

> --

> 2.17.1


The rest LGTM.
Zhong Li Oct. 23, 2018, 9:56 a.m.
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Moritz Barsnick

> Sent: Tuesday, October 23, 2018 4:55 PM

> To: FFmpeg development discussions and patches

> <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation

> feature via call Intel iHD driver

> 

> On Tue, Oct 23, 2018 at 15:52:40 +0800, Zachary Zhou wrote:

> > It supports clockwise rotation by 0/90/180/270 degrees defined in

> > va/va_vpp.h, tested following command line on SKL platform

> 

> Since these angles of rotation are called "transpose" in ffmpeg's other filters

> (transpose, transpose_npp), shouldn't that be the name chosen for this

> functionality?

> 

> It could then also use similar options.

> 

> Just wondering.


Not sure vaapi can expose more angles or not. So I prefer to keep the name as "rotation" which is aligned with vaapi.
But using similar options/suboptions should be a good idea.

> 

> The filter(s) could also use some documentation (doc/filters.texi), but the

> existing vaapi ones don't have any either, so *sigh*.

> 

> Cheers,

> Moritz
Moritz Barsnick Oct. 23, 2018, 12:32 p.m.
On Tue, Oct 23, 2018 at 09:56:04 +0000, Li, Zhong wrote:
> Not sure vaapi can expose more angles or not.

VAAPI's rotation_state only supports those four "angles":
http://01org.github.io/libva_staging_doxygen/struct__VAProcPipelineParameterBuffer.html#ae05cc1f2189c9e85339f7c63e9a61e1c

> But using similar options/suboptions should be a good idea.

Great.

BTW, you could also introduce filters similar to hflip/vflip by using
VAProcPipelineParameterBuffer::mirror_state.

Moritz
Zhong Li Oct. 23, 2018, 12:56 p.m.
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> Of Moritz Barsnick

> Sent: Tuesday, October 23, 2018 8:32 PM

> To: FFmpeg development discussions and patches

> <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation

> feature via call Intel iHD driver

> 

> On Tue, Oct 23, 2018 at 09:56:04 +0000, Li, Zhong wrote:

> > Not sure vaapi can expose more angles or not.

> 

> VAAPI's rotation_state only supports those four "angles":

> http://01org.github.io/libva_staging_doxygen/struct__VAProcPipelineParam

> eterBuffer.html#ae05cc1f2189c9e85339f7c63e9a61e1c 


Yup, I know. I mean vaapi is kept in evolution. I am not sure future version VAAPI will introduce more angles or not.

> 

> > But using similar options/suboptions should be a good idea.

> 

> Great.

> 

> BTW, you could also introduce filters similar to hflip/vflip by using

> VAProcPipelineParameterBuffer::mirror_state.


Good suggestion, :). 
> 

> Moritz
Zachary Zhou Oct. 23, 2018, 1:25 p.m.
I was planning to enable VAAPI rotation and mirroring as two features in two patches.
I am checking VAProcPipelineParameterBuffer::mirror_state, it looks like iHD driver doesn’t support to query mirror_flags via vaQueryVideoProcPipelineCaps currently.


-----Original Message-----
From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Li, Zhong

Sent: Tuesday, October 23, 2018 8:56 PM
To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf 

> Of Moritz Barsnick

> Sent: Tuesday, October 23, 2018 8:32 PM

> To: FFmpeg development discussions and patches 

> <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi 

> rotation feature via call Intel iHD driver

> 

> On Tue, Oct 23, 2018 at 09:56:04 +0000, Li, Zhong wrote:

> > Not sure vaapi can expose more angles or not.

> 

> VAAPI's rotation_state only supports those four "angles":

> http://01org.github.io/libva_staging_doxygen/struct__VAProcPipelinePar

> am eterBuffer.html#ae05cc1f2189c9e85339f7c63e9a61e1c


Yup, I know. I mean vaapi is kept in evolution. I am not sure future version VAAPI will introduce more angles or not.

> 

> > But using similar options/suboptions should be a good idea.

> 

> Great.

> 

> BTW, you could also introduce filters similar to hflip/vflip by using 

> VAProcPipelineParameterBuffer::mirror_state.


Good suggestion, :). 
> 

> Moritz


_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Michael Niedermayer Oct. 23, 2018, 5:05 p.m.
On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:
> It supports clockwise rotation by 0/90/180/270 degrees defined in
> va/va_vpp.h, tested following command line on SKL platform
> 
> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128
> -hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"
> -c:v h264_vaapi output.h264
> ---
>  libavfilter/Makefile        |   1 +
>  libavfilter/allfilters.c    |   1 +
>  libavfilter/vaapi_vpp.h     |   1 +
>  libavfilter/vf_misc_vaapi.c | 122 ++++++++++++++++++++++++++++++++++++
>  4 files changed, 125 insertions(+)

breaks build
make distclean ; ./configure && make -j12
...
libavfilter/vf_misc_vaapi.c: In function ‘rotation_vaapi_build_filter_params’:
libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’
     if (!pipeline_caps.rotation_flags) {
                       ^
libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’
     support_flag = pipeline_caps.rotation_flags &
                                 ^
libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:
libavfilter/vf_misc_vaapi.c:248:15: error: ‘VAProcPipelineParameterBuffer’ has no member named ‘rotation_state’
         params.rotation_state = vpp_ctx->rotation_state;
               ^
make: *** [libavfilter/vf_misc_vaapi.o] Error 1
make: *** Waiting for unfinished jobs....


[...]
Timo Rothenpieler Oct. 23, 2018, 7:07 p.m.
On 23.10.2018 10:55, Moritz Barsnick wrote:
> On Tue, Oct 23, 2018 at 15:52:40 +0800, Zachary Zhou wrote:
>> It supports clockwise rotation by 0/90/180/270 degrees defined in
>> va/va_vpp.h, tested following command line on SKL platform
> 
> Since these angles of rotation are called "transpose" in ffmpeg's other
> filters (transpose, transpose_npp), shouldn't that be the name chosen
> for this functionality?
> 
> It could then also use similar options.
> 
> Just wondering.

The transpose filters do not do plain rotation, they also flip the image 
at the same time. For reasons I'm not sure about that's more useful than 
plain rotation by multiples of 90°.
 From the looks of it, this filter does not do any flipping.
U. Artie Eoff Oct. 23, 2018, 8:49 p.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Michael Niedermayer

> Sent: Tuesday, October 23, 2018 10:06 AM

> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver

> 

> On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:

> > It supports clockwise rotation by 0/90/180/270 degrees defined in

> > va/va_vpp.h, tested following command line on SKL platform

> >

> > ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128

> > -hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"

> > -c:v h264_vaapi output.h264

> > ---

> >  libavfilter/Makefile        |   1 +

> >  libavfilter/allfilters.c    |   1 +

> >  libavfilter/vaapi_vpp.h     |   1 +

> >  libavfilter/vf_misc_vaapi.c | 122 ++++++++++++++++++++++++++++++++++++

> >  4 files changed, 125 insertions(+)

> 

> breaks build

> make distclean ; ./configure && make -j12

> ...

> libavfilter/vf_misc_vaapi.c: In function ‘rotation_vaapi_build_filter_params’:

> libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’

>      if (!pipeline_caps.rotation_flags) {

>                        ^

> libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’

>      support_flag = pipeline_caps.rotation_flags &

>                                  ^

> libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:

> libavfilter/vf_misc_vaapi.c:248:15: error: ‘VAProcPipelineParameterBuffer’ has no member named ‘rotation_state’

>          params.rotation_state = vpp_ctx->rotation_state;

>                ^

> make: *** [libavfilter/vf_misc_vaapi.o] Error 1

> make: *** Waiting for unfinished jobs....

> 

> 


Looks like VPP rotation caps weren't introduced until libva 2.1.0 (in commit cff70165e08ab).
Perhaps, compilation of this feature should be guarded by VA_CHECK_VERSION macro?

> [...]

> --

> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

> 

> Asymptotically faster algorithms should always be preferred if you have

> asymptotical amounts of data
U. Artie Eoff Oct. 23, 2018, 9:05 p.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Eoff, Ullysses A

> Sent: Tuesday, October 23, 2018 1:50 PM

> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver

> 

> > -----Original Message-----

> > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Michael Niedermayer

> > Sent: Tuesday, October 23, 2018 10:06 AM

> > To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>

> > Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver

> >

> > On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:

> > > It supports clockwise rotation by 0/90/180/270 degrees defined in

> > > va/va_vpp.h, tested following command line on SKL platform

> > >

> > > ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128

> > > -hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"

> > > -c:v h264_vaapi output.h264

> > > ---

> > >  libavfilter/Makefile        |   1 +

> > >  libavfilter/allfilters.c    |   1 +

> > >  libavfilter/vaapi_vpp.h     |   1 +

> > >  libavfilter/vf_misc_vaapi.c | 122 ++++++++++++++++++++++++++++++++++++

> > >  4 files changed, 125 insertions(+)

> >

> > breaks build

> > make distclean ; ./configure && make -j12

> > ...

> > libavfilter/vf_misc_vaapi.c: In function ‘rotation_vaapi_build_filter_params’:

> > libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’

> >      if (!pipeline_caps.rotation_flags) {

> >                        ^

> > libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’

> >      support_flag = pipeline_caps.rotation_flags &

> >                                  ^

> > libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:

> > libavfilter/vf_misc_vaapi.c:248:15: error: ‘VAProcPipelineParameterBuffer’ has no member named ‘rotation_state’

> >          params.rotation_state = vpp_ctx->rotation_state;

> >                ^

> > make: *** [libavfilter/vf_misc_vaapi.o] Error 1

> > make: *** Waiting for unfinished jobs....

> >

> >

> 

> Looks like VPP rotation caps weren't introduced until libva 2.1.0 (in commit cff70165e08ab).

> Perhaps, compilation of this feature should be guarded by VA_CHECK_VERSION macro?

> 


That is, VA-API 1.1.0... VA_CHECK_VERSION(1, 1, 0)

> > [...]

> > --

> > Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

> >

> > Asymptotically faster algorithms should always be preferred if you have

> > asymptotical amounts of data

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Mark Thompson Oct. 24, 2018, 11:08 p.m.
On 23/10/18 22:05, Eoff, Ullysses A wrote:
> 
>> -----Original Message-----
>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Eoff, Ullysses A
>> Sent: Tuesday, October 23, 2018 1:50 PM
>> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
>> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver
>>
>>> -----Original Message-----
>>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of Michael Niedermayer
>>> Sent: Tuesday, October 23, 2018 10:06 AM
>>> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
>>> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver
>>>
>>> On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:
>>>> It supports clockwise rotation by 0/90/180/270 degrees defined in
>>>> va/va_vpp.h, tested following command line on SKL platform
>>>>
>>>> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128
>>>> -hwaccel_output_format vaapi -i input.264 -vf "rotation_vaapi=angle=90"
>>>> -c:v h264_vaapi output.h264
>>>> ---
>>>>  libavfilter/Makefile        |   1 +
>>>>  libavfilter/allfilters.c    |   1 +
>>>>  libavfilter/vaapi_vpp.h     |   1 +
>>>>  libavfilter/vf_misc_vaapi.c | 122 ++++++++++++++++++++++++++++++++++++
>>>>  4 files changed, 125 insertions(+)
>>>
>>> breaks build
>>> make distclean ; ./configure && make -j12
>>> ...
>>> libavfilter/vf_misc_vaapi.c: In function ‘rotation_vaapi_build_filter_params’:
>>> libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’
>>>      if (!pipeline_caps.rotation_flags) {
>>>                        ^
>>> libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’ has no member named ‘rotation_flags’
>>>      support_flag = pipeline_caps.rotation_flags &
>>>                                  ^
>>> libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:
>>> libavfilter/vf_misc_vaapi.c:248:15: error: ‘VAProcPipelineParameterBuffer’ has no member named ‘rotation_state’
>>>          params.rotation_state = vpp_ctx->rotation_state;
>>>                ^
>>> make: *** [libavfilter/vf_misc_vaapi.o] Error 1
>>> make: *** Waiting for unfinished jobs....
>>>
>>>
>>
>> Looks like VPP rotation caps weren't introduced until libva 2.1.0 (in commit cff70165e08ab).
>> Perhaps, compilation of this feature should be guarded by VA_CHECK_VERSION macro?
>>
> 
> That is, VA-API 1.1.0... VA_CHECK_VERSION(1, 1, 0)

I think this wants to be a configure option, because the filter will be enabled or not based on it - maybe look for the rotation_state field in VAProcPipelineParameterBuffer with check_struct?

- Mark
Zachary Zhou Oct. 25, 2018, 4:34 a.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of

> Mark Thompson

> Sent: Thursday, October 25, 2018 7:08 AM

> To: ffmpeg-devel@ffmpeg.org

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation

> feature via call Intel iHD driver

> 

> On 23/10/18 22:05, Eoff, Ullysses A wrote:

> >

> >> -----Original Message-----

> >> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> >> Of Eoff, Ullysses A

> >> Sent: Tuesday, October 23, 2018 1:50 PM

> >> To: FFmpeg development discussions and patches

> >> <ffmpeg-devel@ffmpeg.org>

> >> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi

> >> rotation feature via call Intel iHD driver

> >>

> >>> -----Original Message-----

> >>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On

> >>> Behalf Of Michael Niedermayer

> >>> Sent: Tuesday, October 23, 2018 10:06 AM

> >>> To: FFmpeg development discussions and patches

> >>> <ffmpeg-devel@ffmpeg.org>

> >>> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi

> >>> rotation feature via call Intel iHD driver

> >>>

> >>> On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:

> >>>> It supports clockwise rotation by 0/90/180/270 degrees defined in

> >>>> va/va_vpp.h, tested following command line on SKL platform

> >>>>

> >>>> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128

> >>>> -hwaccel_output_format vaapi -i input.264 -vf

> "rotation_vaapi=angle=90"

> >>>> -c:v h264_vaapi output.h264

> >>>> ---

> >>>>  libavfilter/Makefile        |   1 +

> >>>>  libavfilter/allfilters.c    |   1 +

> >>>>  libavfilter/vaapi_vpp.h     |   1 +

> >>>>  libavfilter/vf_misc_vaapi.c | 122

> >>>> ++++++++++++++++++++++++++++++++++++

> >>>>  4 files changed, 125 insertions(+)

> >>>

> >>> breaks build

> >>> make distclean ; ./configure && make -j12 ...

> >>> libavfilter/vf_misc_vaapi.c: In function

> ‘rotation_vaapi_build_filter_params’:

> >>> libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’ has no

> member named ‘rotation_flags’

> >>>      if (!pipeline_caps.rotation_flags) {

> >>>                        ^

> >>> libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’ has no

> member named ‘rotation_flags’

> >>>      support_flag = pipeline_caps.rotation_flags &

> >>>                                  ^

> >>> libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:

> >>> libavfilter/vf_misc_vaapi.c:248:15: error: ‘VAProcPipelineParameterBuffer’

> has no member named ‘rotation_state’

> >>>          params.rotation_state = vpp_ctx->rotation_state;

> >>>                ^

> >>> make: *** [libavfilter/vf_misc_vaapi.o] Error 1

> >>> make: *** Waiting for unfinished jobs....

> >>>

> >>>

> >>

> >> Looks like VPP rotation caps weren't introduced until libva 2.1.0 (in commit

> cff70165e08ab).

> >> Perhaps, compilation of this feature should be guarded by

> VA_CHECK_VERSION macro?

> >>

> >

> > That is, VA-API 1.1.0... VA_CHECK_VERSION(1, 1, 0)

> 

> I think this wants to be a configure option, because the filter will be enabled

> or not based on it - maybe look for the rotation_state field in

> VAProcPipelineParameterBuffer with check_struct?


Good idea to use check_struct, I am ramping up the build script configure. 
Is that possible for following steps - 
1. use check_struct for rotation_state in configure file.
2. push !CONFIG_ROTATION_VAAPI_FILTER=yes to config.mak
3. separate rotation from denoise and sharpness from vf_misc_vaapi.c in a new c source file.

if anyone can give a hint for step 2 will save me a little time.

> 

> - Mark

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Zachary Zhou Oct. 25, 2018, 6:55 a.m.
> -----Original Message-----

> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf Of

> Zhou, Zachary

> Sent: Thursday, October 25, 2018 12:34 PM

> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>

> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation

> feature via call Intel iHD driver

> 

> 

> 

> > -----Original Message-----

> > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On Behalf

> > Of Mark Thompson

> > Sent: Thursday, October 25, 2018 7:08 AM

> > To: ffmpeg-devel@ffmpeg.org

> > Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi

> > rotation feature via call Intel iHD driver

> >

> > On 23/10/18 22:05, Eoff, Ullysses A wrote:

> > >

> > >> -----Original Message-----

> > >> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On

> > >> Behalf Of Eoff, Ullysses A

> > >> Sent: Tuesday, October 23, 2018 1:50 PM

> > >> To: FFmpeg development discussions and patches

> > >> <ffmpeg-devel@ffmpeg.org>

> > >> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi

> > >> rotation feature via call Intel iHD driver

> > >>

> > >>> -----Original Message-----

> > >>> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces@ffmpeg.org] On

> > >>> Behalf Of Michael Niedermayer

> > >>> Sent: Tuesday, October 23, 2018 10:06 AM

> > >>> To: FFmpeg development discussions and patches

> > >>> <ffmpeg-devel@ffmpeg.org>

> > >>> Subject: Re: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable

> > >>> vaapi rotation feature via call Intel iHD driver

> > >>>

> > >>> On Tue, Oct 23, 2018 at 03:52:40PM +0800, Zachary Zhou wrote:

> > >>>> It supports clockwise rotation by 0/90/180/270 degrees defined in

> > >>>> va/va_vpp.h, tested following command line on SKL platform

> > >>>>

> > >>>> ffmpeg -hwaccel vaapi -vaapi_device /dev/dri/renderD128

> > >>>> -hwaccel_output_format vaapi -i input.264 -vf

> > "rotation_vaapi=angle=90"

> > >>>> -c:v h264_vaapi output.h264

> > >>>> ---

> > >>>>  libavfilter/Makefile        |   1 +

> > >>>>  libavfilter/allfilters.c    |   1 +

> > >>>>  libavfilter/vaapi_vpp.h     |   1 +

> > >>>>  libavfilter/vf_misc_vaapi.c | 122

> > >>>> ++++++++++++++++++++++++++++++++++++

> > >>>>  4 files changed, 125 insertions(+)

> > >>>

> > >>> breaks build

> > >>> make distclean ; ./configure && make -j12 ...

> > >>> libavfilter/vf_misc_vaapi.c: In function

> > ‘rotation_vaapi_build_filter_params’:

> > >>> libavfilter/vf_misc_vaapi.c:165:23: error: ‘VAProcPipelineCaps’

> > >>> has no

> > member named ‘rotation_flags’

> > >>>      if (!pipeline_caps.rotation_flags) {

> > >>>                        ^

> > >>> libavfilter/vf_misc_vaapi.c:191:33: error: ‘VAProcPipelineCaps’

> > >>> has no

> > member named ‘rotation_flags’

> > >>>      support_flag = pipeline_caps.rotation_flags &

> > >>>                                  ^

> > >>> libavfilter/vf_misc_vaapi.c: In function ‘misc_vaapi_filter_frame’:

> > >>> libavfilter/vf_misc_vaapi.c:248:15: error:

> ‘VAProcPipelineParameterBuffer’

> > has no member named ‘rotation_state’

> > >>>          params.rotation_state = vpp_ctx->rotation_state;

> > >>>                ^

> > >>> make: *** [libavfilter/vf_misc_vaapi.o] Error 1

> > >>> make: *** Waiting for unfinished jobs....

> > >>>

> > >>>

> > >>

> > >> Looks like VPP rotation caps weren't introduced until libva 2.1.0

> > >> (in commit

> > cff70165e08ab).

> > >> Perhaps, compilation of this feature should be guarded by

> > VA_CHECK_VERSION macro?

> > >>

> > >

> > > That is, VA-API 1.1.0... VA_CHECK_VERSION(1, 1, 0)

> >

> > I think this wants to be a configure option, because the filter will

> > be enabled or not based on it - maybe look for the rotation_state

> > field in VAProcPipelineParameterBuffer with check_struct?

> 

> Good idea to use check_struct, I am ramping up the build script configure.

> Is that possible for following steps -

> 1. use check_struct for rotation_state in configure file.

> 2. push !CONFIG_ROTATION_VAAPI_FILTER=yes to config.mak 3. separate

> rotation from denoise and sharpness from vf_misc_vaapi.c in a new c source

> file.

> 

> if anyone can give a hint for step 2 will save me a little time.


In patch v2 add following in configure file

+    if ! check_struct "va/va.h" "struct _VAProcPipelineCaps" rotation_flags; then
+        disable rotation_vaapi_filter
+    fi

> 

> >

> > - Mark

> > _______________________________________________

> > ffmpeg-devel mailing list

> > ffmpeg-devel@ffmpeg.org

> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

> _______________________________________________

> ffmpeg-devel mailing list

> ffmpeg-devel@ffmpeg.org

> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Patch hide | download patch | download mbox

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 108a2f87d7..81afc100dc 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -349,6 +349,7 @@  OBJS-$(CONFIG_SETRANGE_FILTER)               += vf_setparams.o
 OBJS-$(CONFIG_SETSAR_FILTER)                 += vf_aspect.o
 OBJS-$(CONFIG_SETTB_FILTER)                  += settb.o
 OBJS-$(CONFIG_SHARPNESS_VAAPI_FILTER)        += vf_misc_vaapi.o vaapi_vpp.o
+OBJS-$(CONFIG_ROTATION_VAAPI_FILTER)         += vf_misc_vaapi.o vaapi_vpp.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)               += vf_showinfo.o
 OBJS-$(CONFIG_SHOWPALETTE_FILTER)            += vf_showpalette.o
 OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)          += vf_shuffleframes.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 557590850b..4b90a7f440 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -333,6 +333,7 @@  extern AVFilter ff_vf_setrange;
 extern AVFilter ff_vf_setsar;
 extern AVFilter ff_vf_settb;
 extern AVFilter ff_vf_sharpness_vaapi;
+extern AVFilter ff_vf_rotation_vaapi;
 extern AVFilter ff_vf_showinfo;
 extern AVFilter ff_vf_showpalette;
 extern AVFilter ff_vf_shuffleframes;
diff --git a/libavfilter/vaapi_vpp.h b/libavfilter/vaapi_vpp.h
index 0bc31018d4..cfe19b689f 100644
--- a/libavfilter/vaapi_vpp.h
+++ b/libavfilter/vaapi_vpp.h
@@ -44,6 +44,7 @@  typedef struct VAAPIVPPContext {
     int output_width;   // computed width
     int output_height;  // computed height
 
+    int rotation_state;
     VABufferID         filter_buffers[VAProcFilterCount];
     int                nb_filter_buffers;
 
diff --git a/libavfilter/vf_misc_vaapi.c b/libavfilter/vf_misc_vaapi.c
index 30b808a993..e5d354e3dc 100644
--- a/libavfilter/vf_misc_vaapi.c
+++ b/libavfilter/vf_misc_vaapi.c
@@ -37,6 +37,18 @@ 
 #define SHARPNESS_MAX          64
 #define SHARPNESS_DEFAULT      44
 
+// Rotation angle values
+enum RotationAngle {
+    ROTATION_0   = 0,
+    ROTATION_90  = 90,
+    ROTATION_180 = 180,
+    ROTATION_270 = 270,
+
+    ROTATION_MIN     = ROTATION_0,
+    ROTATION_MAX     = ROTATION_270,
+    ROTATION_DEFAULT = ROTATION_0,
+};
+
 typedef struct DenoiseVAAPIContext {
     VAAPIVPPContext vpp_ctx; // must be the first field
 
@@ -49,6 +61,12 @@  typedef struct SharpnessVAAPIContext {
     int sharpness;       // enable sharpness.
 } SharpnessVAAPIContext;
 
+typedef struct RotationVAAPIContext {
+    VAAPIVPPContext vpp_ctx; // must be the first field
+
+    int rotation;        // enable rotation.
+} RotationVAAPIContext;
+
 static float map(int x, int in_min, int in_max, float out_min, float out_max)
 {
     double slope, output;
@@ -123,6 +141,64 @@  static int sharpness_vaapi_build_filter_params(AVFilterContext *avctx)
     return 0;
 }
 
+static int rotation_vaapi_build_filter_params(AVFilterContext *avctx)
+{
+    VAAPIVPPContext *vpp_ctx  = avctx->priv;
+    RotationVAAPIContext *ctx = avctx->priv;
+
+    VAStatus vas;
+    int support_flag;
+
+    VAProcPipelineCaps pipeline_caps;
+
+    memset(&pipeline_caps, 0, sizeof(pipeline_caps));
+    vas = vaQueryVideoProcPipelineCaps(vpp_ctx->hwctx->display,
+                                       vpp_ctx->va_context,
+                                       NULL, 0,
+                                       &pipeline_caps);
+    if (vas != VA_STATUS_SUCCESS) {
+        av_log(avctx, AV_LOG_ERROR, "Failed to query pipeline "
+               "caps: %d (%s).\n", vas, vaErrorStr(vas));
+        return AVERROR(EIO);
+    }
+
+    if (!pipeline_caps.rotation_flags) {
+        av_log(avctx, AV_LOG_ERROR, "VAAPI driver doesn't support rotation\n");
+        return AVERROR(EINVAL);
+    }
+
+    switch (ctx->rotation) {
+    case ROTATION_0:
+        vpp_ctx->rotation_state = VA_ROTATION_NONE;
+        break;
+    case ROTATION_90:
+        vpp_ctx->rotation_state = VA_ROTATION_90;
+        break;
+    case ROTATION_180:
+        vpp_ctx->rotation_state = VA_ROTATION_180;
+        break;
+    case ROTATION_270:
+        vpp_ctx->rotation_state = VA_ROTATION_270;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "Failed to set rotation_state to %d. "
+               "Clockwise %d, %d, %d and %d are only supported\n",
+               ctx->rotation,
+               ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270);
+        return AVERROR(EINVAL);
+    }
+
+    support_flag = pipeline_caps.rotation_flags &
+                   (1 << vpp_ctx->rotation_state);
+    if (!support_flag) {
+        av_log(avctx, AV_LOG_ERROR, "VAAPI driver doesn't support %d\n",
+               ctx->rotation);
+        return AVERROR(EINVAL);
+    }
+
+    return 0;
+}
+
 static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
 {
     AVFilterContext *avctx   = inlink->dst;
@@ -164,6 +240,19 @@  static int misc_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)
         .height = input_frame->height,
     };
 
+    switch (vpp_ctx->rotation_state) {
+    case VA_ROTATION_NONE:
+    case VA_ROTATION_90:
+    case VA_ROTATION_180:
+    case VA_ROTATION_270:
+        params.rotation_state = vpp_ctx->rotation_state;
+        break;
+    default:
+        av_log(avctx, AV_LOG_ERROR, "VAAPI doesn't support %d\n",
+               vpp_ctx->rotation_state);
+        goto fail;
+    }
+
     if (vpp_ctx->nb_filter_buffers) {
         params.filters     = &vpp_ctx->filter_buffers[0];
         params.num_filters = vpp_ctx->nb_filter_buffers;
@@ -225,6 +314,18 @@  static av_cold int sharpness_vaapi_init(AVFilterContext *avctx)
     return 0;
 }
 
+static av_cold int rotation_vaapi_init(AVFilterContext *avctx)
+{
+    VAAPIVPPContext *vpp_ctx = avctx->priv;
+
+    ff_vaapi_vpp_ctx_init(avctx);
+    vpp_ctx->pipeline_uninit     = ff_vaapi_vpp_pipeline_uninit;
+    vpp_ctx->build_filter_params = rotation_vaapi_build_filter_params;
+    vpp_ctx->output_format       = AV_PIX_FMT_NONE;
+
+    return 0;
+}
+
 #define DOFFSET(x) offsetof(DenoiseVAAPIContext, x)
 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
 static const AVOption denoise_vaapi_options[] = {
@@ -240,8 +341,16 @@  static const AVOption sharpness_vaapi_options[] = {
     { NULL },
 };
 
+#define ROFFSET(x) offsetof(RotationVAAPIContext, x)
+static const AVOption rotation_vaapi_options[] = {
+    { "angle", "clockwise rotation angle 0/90/180/270 are only supported",
+      ROFFSET(rotation), AV_OPT_TYPE_INT, { .i64 = ROTATION_DEFAULT }, ROTATION_MIN, ROTATION_MAX, .flags = FLAGS },
+    { NULL },
+};
+
 AVFILTER_DEFINE_CLASS(denoise_vaapi);
 AVFILTER_DEFINE_CLASS(sharpness_vaapi);
+AVFILTER_DEFINE_CLASS(rotation_vaapi);
 
 static const AVFilterPad misc_vaapi_inputs[] = {
     {
@@ -287,3 +396,16 @@  AVFilter ff_vf_sharpness_vaapi = {
     .priv_class    = &sharpness_vaapi_class,
     .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
 };
+
+AVFilter ff_vf_rotation_vaapi = {
+    .name          = "rotation_vaapi",
+    .description   = NULL_IF_CONFIG_SMALL("VAAPI VPP for rotation"),
+    .priv_size     = sizeof(RotationVAAPIContext),
+    .init          = &rotation_vaapi_init,
+    .uninit        = &ff_vaapi_vpp_ctx_uninit,
+    .query_formats = &ff_vaapi_vpp_query_formats,
+    .inputs        = misc_vaapi_inputs,
+    .outputs       = misc_vaapi_outputs,
+    .priv_class    = &rotation_vaapi_class,
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
+};