From patchwork Tue Oct 23 07:52:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zachary Zhou X-Patchwork-Id: 10754 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 2B9B244A4FE for ; Tue, 23 Oct 2018 10:54:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 761FC68A602; Tue, 23 Oct 2018 10:54:21 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga12.intel.com (mga12.intel.com [192.55.52.136]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CD71A68A253 for ; Tue, 23 Oct 2018 10:54:19 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga106.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 23 Oct 2018 00:54:45 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.54,415,1534834800"; d="scan'208";a="80860815" Received: from u18-skl-zz.sh.intel.com ([10.239.159.29]) by fmsmga008.fm.intel.com with ESMTP; 23 Oct 2018 00:54:45 -0700 From: Zachary Zhou To: ffmpeg-devel@ffmpeg.org Date: Tue, 23 Oct 2018 15:52:40 +0800 Message-Id: <20181023075240.2358-1-zachary.zhou@intel.com> X-Mailer: git-send-email 2.17.1 Subject: [FFmpeg-devel] [PATCH] libavfilter/vaapi: enable vaapi rotation feature via call Intel iHD driver X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: zachary.zhou@intel.com MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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. +} 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, +};