[FFmpeg-devel] [PATCH 2/2] lavf/vf_vpp_qsv: add support for QSV transpose filter
Fu, Linjie
linjie.fu at intel.com
Wed Jul 10 12:37:47 EEST 2019
> -----Original Message-----
> From: Li, Zhong
> Sent: Monday, July 8, 2019 11:16
> To: FFmpeg development discussions and patches <ffmpeg-
> devel at ffmpeg.org>
> Cc: Fu, Linjie <linjie.fu at intel.com>
> Subject: RE: [FFmpeg-devel] [PATCH 2/2] lavf/vf_vpp_qsv: add support for
> QSV transpose filter
>
> > From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On
> Behalf
> > Of Linjie Fu
> > Sent: Tuesday, June 18, 2019 10:53 PM
> > To: ffmpeg-devel at ffmpeg.org
> > Cc: Fu, Linjie <linjie.fu at intel.com>
> > Subject: [FFmpeg-devel] [PATCH 2/2] lavf/vf_vpp_qsv: add support for
> QSV
> > transpose filter
> >
> > Add transpose support for qsv_vpp with rotate and hflip:
> > - rotate: [0, 3] support clockwise rotation of 0, 90, 180, 270;
> > - hflip: [0, 1] support horizontal flip;
> >
> > Configure with:
> > {"cclock_hflip","clock","cclock","clock_hflip","reversal","hflip","vflip"}
> >
> > Limitation:
> > If pipeline contains resize, mirroring and other, VPP skips other filters in
> > MSDK when IOPattern equals d3d->d3d. So "cclock_hflip, clock_hflip, vflip"
> > will not work in d3d->d3d condition.
>
> How user can aware this if not check the log message? And any MSDK github
> issue created?
Yes, a PR has been sent to support mirror when working on IOPattern equals d3d->d3d.
https://github.com/Intel-Media-SDK/MediaSDK/pull/1491
> > CMD:
> > ffmpeg -hwaccel qsv -c:v h264_qsv -i input.h264
> > -vf 'format=qsv,vpp_qsv=transpose=clock' -c:v h264_qsv output.h264
> >
> > ffmpeg -init_hw_device qsv=foo -filter_hw_device foo -f rawvideo
> > -pix_fmt nv12 -s:v 1920x1080 -i input.nv12 -vf
> >
> >
> 'hwupload=extra_hw_frames=64,format=qsv,vpp_qsv=transpose=cclock_hf
> li
> > p'
> > -f rawvideo -pix_fmt nv12 -y ./transpose.yuv
>
> What is the platform tested? Probably adding MFXVideoVPP_Query() to
> runtime capability checking is a good idea.
Tested on KBL, it should have been supported early.
Will think of adding MFXVideoVPP_Query() in a separate patch.
> > Signed-off-by: Linjie Fu <linjie.fu at intel.com>
> > ---
> > libavfilter/vf_vpp_qsv.c | 95
> > +++++++++++++++++++++++++++++++++++++++-
> > 1 file changed, 93 insertions(+), 2 deletions(-)
> >
> > diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index
> > dd05e8baff..974fc7a255 100644
> > --- a/libavfilter/vf_vpp_qsv.c
> > +++ b/libavfilter/vf_vpp_qsv.c
> > @@ -36,12 +36,15 @@
> > #include "libavformat/avformat.h"
> >
> > #include "qsvvpp.h"
> > +#include "transpose.h"
> >
> > #define OFFSET(x) offsetof(VPPContext, x) #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 +57,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 +75,10 @@ typedef struct VPPContext{
> > int crop_x;
> > int crop_y;
> >
> > + int transpose;
> > + int rotate; /* rotate angle : [0, 90, 180, 270] */
> > + int hflip; /* flip mode : 0 = off, 1 = HORIZONTAL
> > flip */
> > +
> > /* param for the procamp */
> > int procamp; /* enable procamp */
> > float hue;
> > @@ -95,6 +104,15 @@ 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},
> >
> > + { "transpose", "set transpose direction", OFFSET(transpose),
> > AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 6, FLAGS, "transpose"},
> > + { "cclock_hflip", "rotate counter-clockwise with horizontal flip",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_CCLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
> > + { "clock", "rotate clockwise",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_CLOCK }, .flags=FLAGS, .unit = "transpose" },
> > + { "cclock", "rotate counter-clockwise",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_CCLOCK }, .flags=FLAGS, .unit = "transpose" },
> > + { "clock_hflip", "rotate clockwise with horizontal flip",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_CLOCK_FLIP }, .flags=FLAGS, .unit = "transpose" },
> > + { "reversal", "rotate by half-turn",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_REVERSAL }, .flags=FLAGS, .unit = "transpose" },
> > + { "hflip", "flip horizontally",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_HFLIP }, .flags=FLAGS, .unit = "transpose" },
> > + { "vflip", "flip vertically",
> > 0, AV_OPT_TYPE_CONST, { .i64 =
> > TRANSPOSE_VFLIP }, .flags=FLAGS, .unit = "transpose" },
> > +
> > { "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 +340,81 @@ static int config_output(AVFilterLink *outlink)
> > param.ext_buf[param.num_ext_buf++] =
> > (mfxExtBuffer*)&vpp->procamp_conf;
> > }
> >
> > + if (vpp->transpose >= 0) {
> > + switch (vpp->transpose) {
> > + case TRANSPOSE_CCLOCK_FLIP:
> > + vpp->rotate = MFX_ANGLE_270;
> > + vpp->hflip = MFX_MIRRORING_HORIZONTAL;
>
> Will compile broken if no QSV_HAVE_ROTATION checking?
Yes, thanks for remind.
>
> > + break;
> > + case TRANSPOSE_CLOCK:
> > + vpp->rotate = MFX_ANGLE_90;
> > + vpp->hflip = MFX_MIRRORING_DISABLED;
> > + break;
> > + case TRANSPOSE_CCLOCK:
> > + vpp->rotate = MFX_ANGLE_270;
> > + vpp->hflip = MFX_MIRRORING_DISABLED;
> > + break;
> > + case TRANSPOSE_CLOCK_FLIP:
> > + vpp->rotate = MFX_ANGLE_90;
> > + vpp->hflip = MFX_MIRRORING_HORIZONTAL;
> > + break;
> > + case TRANSPOSE_REVERSAL:
> > + vpp->rotate = MFX_ANGLE_180;
> > + vpp->hflip = MFX_MIRRORING_DISABLED;
> > + break;
> > + case TRANSPOSE_HFLIP:
> > + vpp->rotate = MFX_ANGLE_0;
> > + vpp->hflip = MFX_MIRRORING_HORIZONTAL;
> > + break;
> > + case TRANSPOSE_VFLIP:
> > + vpp->rotate = MFX_ANGLE_180;
> > + vpp->hflip = MFX_MIRRORING_HORIZONTAL;
> > + break;
> > + default:
> > + av_log(ctx, AV_LOG_ERROR, "Failed to set transpose mode
> > to %d.\n", vpp->transpose);
> > + return AVERROR(EINVAL);
> > + }
> > + }
> > +
> > + if (vpp->rotate) {
> > +#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 = vpp->rotate;
> > +
> > + if (MFX_ANGLE_90 == vpp->rotate || MFX_ANGLE_270 ==
> > vpp->rotate) {
> > + FFSWAP(int, vpp->out_width, vpp->out_height);
> > + FFSWAP(int, outlink->w, outlink->h);
> > + av_log(ctx, AV_LOG_DEBUG, "Swap width and height for
> > clock/cclock rotation.\n");
> > + }
> > +
> > + param.ext_buf[param.num_ext_buf++] =
> > +(mfxExtBuffer*)&vpp->rotation_conf;
> > +#else
> > + av_log(ctx, AV_LOG_WARNING, "The QSV VPP rotate option is "
> > + "not supported with this MSDK version.\n");
> > + vpp->rotate = 0;
> > +#endif
> > + }
> > +
> > + if (vpp->hflip) {
> > +#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->hflip;
> > +
> > + param.ext_buf[param.num_ext_buf++] =
> > +(mfxExtBuffer*)&vpp->mirroring_conf;
> > +#else
> > + av_log(ctx, AV_LOG_WARNING, "The QSV VPP hflip option is "
> > + "not supported with this MSDK version.\n");
> > + vpp->hflip = 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->rotate || vpp->hflip || vpp->detail || vpp->procamp ||
> > + inlink->w != outlink->w || inlink->h != outlink->h)
>
> Make the additional " vpp->rotate " and " vpp->hflip " at the end should be
> better.
will follow to make it more clear for review.
> > return ff_qsvvpp_create(ctx, &vpp->qsv, ¶m);
> > else {
> > av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n");
> > --
> > 2.17.1
>
> Looks good as a whole if above comments addressed.
More information about the ffmpeg-devel
mailing list