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

Mark Thompson sw at jkqxz.net
Sun Mar 17 15:58:54 EET 2019


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 at 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


More information about the ffmpeg-devel mailing list