[FFmpeg-devel,1/2] lavf/vf_vpp_qsv: add transpose support for QSV VPP

Submitted by Linjie Fu on March 15, 2019, 4:34 p.m.

Details

Message ID 20190315163442.28230-1-linjie.fu@intel.com
State New
Headers show

Commit Message

Linjie Fu March 15, 2019, 4:34 p.m.
Add transpose support for qsv_vpp:
    - rotation: [0, 3] support clockwise rotation of 0, 90, 180, 270;
    - mirror:   [0, 1] support horizontal mirroring;

ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
    -vf 'format=qsv,vpp_qsv=rotation=1' -c:v h264_qsv output.h264
ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
    -vf 'format=qsv,vpp_qsv=mirror=1' -c:v h264_qsv output.h264
ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
    -vf 'format=qsv,vpp_qsv=rotation=2,vpp_qsv=mirror=1' -c:v h264_qsv output.h264

Signed-off-by: Linjie Fu <linjie.fu@intel.com>
---
 libavfilter/vf_vpp_qsv.c | 45 ++++++++++++++++++++++++++++++++++++++--
 1 file changed, 43 insertions(+), 2 deletions(-)

Comments

Mark Thompson March 17, 2019, 1:58 p.m.
On 15/03/2019 16:34, Linjie Fu wrote:
> Add transpose support for qsv_vpp:
>     - rotation: [0, 3] support clockwise rotation of 0, 90, 180, 270;
>     - mirror:   [0, 1] support horizontal mirroring;
> 
> ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
>     -vf 'format=qsv,vpp_qsv=rotation=1' -c:v h264_qsv output.h264
> ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
>     -vf 'format=qsv,vpp_qsv=mirror=1' -c:v h264_qsv output.h264
> ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264
>     -vf 'format=qsv,vpp_qsv=rotation=2,vpp_qsv=mirror=1' -c:v h264_qsv output.h264
> 
> Signed-off-by: Linjie Fu <linjie.fu@intel.com>
> ---
>  libavfilter/vf_vpp_qsv.c | 45 ++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 43 insertions(+), 2 deletions(-)
> 
> diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
> index 41a9f38962..edbe944321 100644
> --- a/libavfilter/vf_vpp_qsv.c
> +++ b/libavfilter/vf_vpp_qsv.c
> @@ -41,7 +41,9 @@
>  #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
>  
>  /* number of video enhancement filters */
> -#define ENH_FILTERS_COUNT (5)
> +#define ENH_FILTERS_COUNT (7)
> +#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)
> +#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
>  
>  typedef struct VPPContext{
>      const AVClass *class;
> @@ -54,6 +56,8 @@ typedef struct VPPContext{
>      mfxExtVPPDenoise denoise_conf;
>      mfxExtVPPDetail detail_conf;
>      mfxExtVPPProcAmp procamp_conf;
> +    mfxExtVPPRotation rotation_conf;
> +    mfxExtVPPMirroring mirroring_conf;
>  
>      int out_width;
>      int out_height;
> @@ -70,6 +74,9 @@ typedef struct VPPContext{
>      int crop_x;
>      int crop_y;
>  
> +    int rotation;               /* rotation mode : 0=0, 1=90, 2=180, 3=270 */
> +    int mirror;                 /* mirror mode : 0=off, 1=HORIZONTAL */
> +
>      /* param for the procamp */
>      int    procamp;            /* enable procamp */
>      float  hue;
> @@ -95,6 +102,9 @@ static const AVOption options[] = {
>      { "contrast",    "ProcAmp contrast",             OFFSET(contrast),    AV_OPT_TYPE_FLOAT,    { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
>      { "brightness",  "ProcAmp brightness",           OFFSET(brightness),  AV_OPT_TYPE_FLOAT,    { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
>  
> +    { "rotation",    "clockwise rotation: 90 * [0, 3]", OFFSET(rotation), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 3, .flags = FLAGS},
> +    { "mirror",      "horizontal mirror [0, 1]",        OFFSET(mirror),   AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 1, .flags = FLAGS},

Please use the same names as other filters doing transpose/rotate operations.

> +
>      { "cw",   "set the width crop area expression",   OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, CHAR_MIN, CHAR_MAX, FLAGS },
>      { "ch",   "set the height crop area expression",  OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, CHAR_MIN, CHAR_MAX, FLAGS },
>      { "cx",   "set the x crop area expression",       OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, CHAR_MIN, CHAR_MAX, FLAGS },
> @@ -322,8 +332,39 @@ static int config_output(AVFilterLink *outlink)
>          param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf;
>      }
>  
> +    if (vpp->rotation) {
> +#ifdef QSV_HAVE_ROTATION
> +        memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
> +        vpp->rotation_conf.Header.BufferId  = MFX_EXTBUFF_VPP_ROTATION;
> +        vpp->rotation_conf.Header.BufferSz  = sizeof(mfxExtVPPRotation);
> +        vpp->rotation_conf.Angle = 90 * vpp->rotation;
> +
> +        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
> +#else
> +        av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotation option is "
> +            "not supported with this MSDK version.\n");
> +        vpp->rotation = 0;
> +#endif
> +    }
> +
> +    if (vpp->mirror) {
> +#ifdef QSV_HAVE_MIRRORING
> +        memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
> +        vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
> +        vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
> +        vpp->mirroring_conf.Type = vpp->mirror;
> +
> +        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
> +#else
> +        av_log(ctx, AV_LOG_WARNING, "The QSV VPP mirror option is "
> +            "not supported with this MSDK version.\n");
> +        vpp->mirror = 0;
> +#endif
> +    }
> +
>      if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
> -        vpp->detail || vpp->procamp || inlink->w != outlink->w || inlink->h != outlink->h)
> +        vpp->rotation || vpp->mirror || vpp->detail || vpp->procamp ||
> +        inlink->w != outlink->w || inlink->h != outlink->h)
>          return ff_qsvvpp_create(ctx, &vpp->qsv, &param);
>      else {
>          av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
> 

I think there should be something to make the default behaviour for the cases where you would expect the axes to be swapped to do that.  It would be surprising for rotating a portait 1080x1920 input to produce a squashed 1080x1920 output rather than 1920x1080.

Thanks,

- Mark
Linjie Fu March 18, 2019, 5:34 a.m.
> -----Original Message-----

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

> Of Mark Thompson

> Sent: Sunday, March 17, 2019 21:59

> To: ffmpeg-devel@ffmpeg.org

> Subject: Re: [FFmpeg-devel] [PATCH 1/2] lavf/vf_vpp_qsv: add transpose

> support for QSV VPP

> 

> On 15/03/2019 16:34, Linjie Fu wrote:

> > Add transpose support for qsv_vpp:

> >     - rotation: [0, 3] support clockwise rotation of 0, 90, 180, 270;

> >     - mirror:   [0, 1] support horizontal mirroring;

> >

> > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> >     -vf 'format=qsv,vpp_qsv=rotation=1' -c:v h264_qsv output.h264

> > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> >     -vf 'format=qsv,vpp_qsv=mirror=1' -c:v h264_qsv output.h264

> > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> >     -vf 'format=qsv,vpp_qsv=rotation=2,vpp_qsv=mirror=1' -c:v h264_qsv

> output.h264

> >

> > Signed-off-by: Linjie Fu <linjie.fu@intel.com>

> > ---

> >  libavfilter/vf_vpp_qsv.c | 45

> ++++++++++++++++++++++++++++++++++++++--

> >  1 file changed, 43 insertions(+), 2 deletions(-)

> >

> > diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c

> > index 41a9f38962..edbe944321 100644

> > --- a/libavfilter/vf_vpp_qsv.c

> > +++ b/libavfilter/vf_vpp_qsv.c

> > @@ -41,7 +41,9 @@

> >  #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM |

> AV_OPT_FLAG_FILTERING_PARAM)

> >

> >  /* number of video enhancement filters */

> > -#define ENH_FILTERS_COUNT (5)

> > +#define ENH_FILTERS_COUNT (7)

> > +#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)

> > +#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)

> >

> >  typedef struct VPPContext{

> >      const AVClass *class;

> > @@ -54,6 +56,8 @@ typedef struct VPPContext{

> >      mfxExtVPPDenoise denoise_conf;

> >      mfxExtVPPDetail detail_conf;

> >      mfxExtVPPProcAmp procamp_conf;

> > +    mfxExtVPPRotation rotation_conf;

> > +    mfxExtVPPMirroring mirroring_conf;

> >

> >      int out_width;

> >      int out_height;

> > @@ -70,6 +74,9 @@ typedef struct VPPContext{

> >      int crop_x;

> >      int crop_y;

> >

> > +    int rotation;               /* rotation mode : 0=0, 1=90, 2=180, 3=270 */

> > +    int mirror;                 /* mirror mode : 0=off, 1=HORIZONTAL */

> > +

> >      /* param for the procamp */

> >      int    procamp;            /* enable procamp */

> >      float  hue;

> > @@ -95,6 +102,9 @@ static const AVOption options[] = {

> >      { "contrast",    "ProcAmp contrast",             OFFSET(contrast),

> AV_OPT_TYPE_FLOAT,    { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},

> >      { "brightness",  "ProcAmp brightness",           OFFSET(brightness),

> AV_OPT_TYPE_FLOAT,    { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},

> >

> > +    { "rotation",    "clockwise rotation: 90 * [0, 3]", OFFSET(rotation),

> AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 3, .flags = FLAGS},

> > +    { "mirror",      "horizontal mirror [0, 1]",        OFFSET(mirror),

> AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 1, .flags = FLAGS},

> 

> Please use the same names as other filters doing transpose/rotate

> operations.

> 

Is it acceptable updating the names into "rotate" and "hflip" separately?
Or they should be combined into "transpose" like vaapi_transpose does?
> 

> I think there should be something to make the default behaviour for the

> cases where you would expect the axes to be swapped to do that.  It would

> be surprising for rotating a portait 1080x1920 input to produce a squashed

> 1080x1920 output rather than 1920x1080.


Thanks, will add FFSWAP(int, vpp->out_width, vpp->out_height) to swap width
and height for clock/cclock rotation.
Linjie Fu May 22, 2019, 4:31 a.m.
> -----Original Message-----

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

> Of Fu, Linjie

> Sent: Monday, March 18, 2019 13:35

> To: FFmpeg development discussions and patches <ffmpeg-

> devel@ffmpeg.org>

> Cc: Mark Thompson <sw@jkqxz.net>

> Subject: Re: [FFmpeg-devel] [PATCH 1/2] lavf/vf_vpp_qsv: add transpose

> support for QSV VPP

> 

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

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

> Behalf

> > Of Mark Thompson

> > Sent: Sunday, March 17, 2019 21:59

> > To: ffmpeg-devel@ffmpeg.org

> > Subject: Re: [FFmpeg-devel] [PATCH 1/2] lavf/vf_vpp_qsv: add transpose

> > support for QSV VPP

> >

> > On 15/03/2019 16:34, Linjie Fu wrote:

> > > Add transpose support for qsv_vpp:

> > >     - rotation: [0, 3] support clockwise rotation of 0, 90, 180, 270;

> > >     - mirror:   [0, 1] support horizontal mirroring;

> > >

> > > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> > >     -vf 'format=qsv,vpp_qsv=rotation=1' -c:v h264_qsv output.h264

> > > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> > >     -vf 'format=qsv,vpp_qsv=mirror=1' -c:v h264_qsv output.h264

> > > ffmpeg -hwaccel qsv -v verbose -c:v h264_qsv -i input.h264

> > >     -vf 'format=qsv,vpp_qsv=rotation=2,vpp_qsv=mirror=1' -c:v h264_qsv

> > output.h264

> > >

> > > Signed-off-by: Linjie Fu <linjie.fu@intel.com>

> > > ---

> > >  libavfilter/vf_vpp_qsv.c | 45

> > ++++++++++++++++++++++++++++++++++++++--

> > >  1 file changed, 43 insertions(+), 2 deletions(-)

> > >

> > > diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c

> > > index 41a9f38962..edbe944321 100644

> > > --- a/libavfilter/vf_vpp_qsv.c

> > > +++ b/libavfilter/vf_vpp_qsv.c

> > > @@ -41,7 +41,9 @@

> > >  #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM |

> > AV_OPT_FLAG_FILTERING_PARAM)

> > >

> > >  /* number of video enhancement filters */

> > > -#define ENH_FILTERS_COUNT (5)

> > > +#define ENH_FILTERS_COUNT (7)

> > > +#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)

> > > +#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)

> > >

> > >  typedef struct VPPContext{

> > >      const AVClass *class;

> > > @@ -54,6 +56,8 @@ typedef struct VPPContext{

> > >      mfxExtVPPDenoise denoise_conf;

> > >      mfxExtVPPDetail detail_conf;

> > >      mfxExtVPPProcAmp procamp_conf;

> > > +    mfxExtVPPRotation rotation_conf;

> > > +    mfxExtVPPMirroring mirroring_conf;

> > >

> > >      int out_width;

> > >      int out_height;

> > > @@ -70,6 +74,9 @@ typedef struct VPPContext{

> > >      int crop_x;

> > >      int crop_y;

> > >

> > > +    int rotation;               /* rotation mode : 0=0, 1=90, 2=180, 3=270 */

> > > +    int mirror;                 /* mirror mode : 0=off, 1=HORIZONTAL */

> > > +

> > >      /* param for the procamp */

> > >      int    procamp;            /* enable procamp */

> > >      float  hue;

> > > @@ -95,6 +102,9 @@ static const AVOption options[] = {

> > >      { "contrast",    "ProcAmp contrast",             OFFSET(contrast),

> > AV_OPT_TYPE_FLOAT,    { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},

> > >      { "brightness",  "ProcAmp brightness",           OFFSET(brightness),

> > AV_OPT_TYPE_FLOAT,    { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},

> > >

> > > +    { "rotation",    "clockwise rotation: 90 * [0, 3]", OFFSET(rotation),

> > AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 3, .flags = FLAGS},

> > > +    { "mirror",      "horizontal mirror [0, 1]",        OFFSET(mirror),

> > AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 1, .flags = FLAGS},

> >

> > Please use the same names as other filters doing transpose/rotate

> > operations.

> >

> Is it acceptable updating the names into "rotate" and "hflip" separately?

> Or they should be combined into "transpose" like vaapi_transpose does?

> >

> > I think there should be something to make the default behaviour for the

> > cases where you would expect the axes to be swapped to do that.  It

> would

> > be surprising for rotating a portait 1080x1920 input to produce a squashed

> > 1080x1920 output rather than 1920x1080.

> 

> Thanks, will add FFSWAP(int, vpp->out_width, vpp->out_height) to swap

> width

> and height for clock/cclock rotation.


Ping for the updated patch?
https://patchwork.ffmpeg.org/patch/12351/

Patch hide | download patch | download mbox

diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c
index 41a9f38962..edbe944321 100644
--- a/libavfilter/vf_vpp_qsv.c
+++ b/libavfilter/vf_vpp_qsv.c
@@ -41,7 +41,9 @@ 
 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM)
 
 /* number of video enhancement filters */
-#define ENH_FILTERS_COUNT (5)
+#define ENH_FILTERS_COUNT (7)
+#define QSV_HAVE_ROTATION  QSV_VERSION_ATLEAST(1, 17)
+#define QSV_HAVE_MIRRORING QSV_VERSION_ATLEAST(1, 19)
 
 typedef struct VPPContext{
     const AVClass *class;
@@ -54,6 +56,8 @@  typedef struct VPPContext{
     mfxExtVPPDenoise denoise_conf;
     mfxExtVPPDetail detail_conf;
     mfxExtVPPProcAmp procamp_conf;
+    mfxExtVPPRotation rotation_conf;
+    mfxExtVPPMirroring mirroring_conf;
 
     int out_width;
     int out_height;
@@ -70,6 +74,9 @@  typedef struct VPPContext{
     int crop_x;
     int crop_y;
 
+    int rotation;               /* rotation mode : 0=0, 1=90, 2=180, 3=270 */
+    int mirror;                 /* mirror mode : 0=off, 1=HORIZONTAL */
+
     /* param for the procamp */
     int    procamp;            /* enable procamp */
     float  hue;
@@ -95,6 +102,9 @@  static const AVOption options[] = {
     { "contrast",    "ProcAmp contrast",             OFFSET(contrast),    AV_OPT_TYPE_FLOAT,    { .dbl = 1.0 }, 0.0, 10.0, .flags = FLAGS},
     { "brightness",  "ProcAmp brightness",           OFFSET(brightness),  AV_OPT_TYPE_FLOAT,    { .dbl = 0.0 }, -100.0, 100.0, .flags = FLAGS},
 
+    { "rotation",    "clockwise rotation: 90 * [0, 3]", OFFSET(rotation), AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 3, .flags = FLAGS},
+    { "mirror",      "horizontal mirror [0, 1]",        OFFSET(mirror),   AV_OPT_TYPE_INT,      { .i64 = 0 }, 0, 1, .flags = FLAGS},
+
     { "cw",   "set the width crop area expression",   OFFSET(cw), AV_OPT_TYPE_STRING, { .str = "iw" }, CHAR_MIN, CHAR_MAX, FLAGS },
     { "ch",   "set the height crop area expression",  OFFSET(ch), AV_OPT_TYPE_STRING, { .str = "ih" }, CHAR_MIN, CHAR_MAX, FLAGS },
     { "cx",   "set the x crop area expression",       OFFSET(cx), AV_OPT_TYPE_STRING, { .str = "(in_w-out_w)/2" }, CHAR_MIN, CHAR_MAX, FLAGS },
@@ -322,8 +332,39 @@  static int config_output(AVFilterLink *outlink)
         param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf;
     }
 
+    if (vpp->rotation) {
+#ifdef QSV_HAVE_ROTATION
+        memset(&vpp->rotation_conf, 0, sizeof(mfxExtVPPRotation));
+        vpp->rotation_conf.Header.BufferId  = MFX_EXTBUFF_VPP_ROTATION;
+        vpp->rotation_conf.Header.BufferSz  = sizeof(mfxExtVPPRotation);
+        vpp->rotation_conf.Angle = 90 * vpp->rotation;
+
+        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->rotation_conf;
+#else
+        av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotation option is "
+            "not supported with this MSDK version.\n");
+        vpp->rotation = 0;
+#endif
+    }
+
+    if (vpp->mirror) {
+#ifdef QSV_HAVE_MIRRORING
+        memset(&vpp->mirroring_conf, 0, sizeof(mfxExtVPPMirroring));
+        vpp->mirroring_conf.Header.BufferId = MFX_EXTBUFF_VPP_MIRRORING;
+        vpp->mirroring_conf.Header.BufferSz = sizeof(mfxExtVPPMirroring);
+        vpp->mirroring_conf.Type = vpp->mirror;
+
+        param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->mirroring_conf;
+#else
+        av_log(ctx, AV_LOG_WARNING, "The QSV VPP mirror option is "
+            "not supported with this MSDK version.\n");
+        vpp->mirror = 0;
+#endif
+    }
+
     if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise ||
-        vpp->detail || vpp->procamp || inlink->w != outlink->w || inlink->h != outlink->h)
+        vpp->rotation || vpp->mirror || vpp->detail || vpp->procamp ||
+        inlink->w != outlink->w || inlink->h != outlink->h)
         return ff_qsvvpp_create(ctx, &vpp->qsv, &param);
     else {
         av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");