[FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver
Li, Zhong
zhong.li at intel.com
Tue Oct 23 12:52:49 EEST 2018
> From: ffmpeg-devel [mailto:ffmpeg-devel-bounces at ffmpeg.org] On Behalf
> Of Zachary Zhou
> Sent: Tuesday, October 23, 2018 3:53 PM
> To: ffmpeg-devel at ffmpeg.org
> Cc: Zhou, Zachary <zachary.zhou at 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.
More information about the ffmpeg-devel
mailing list