PR #23536 opened by ArazIusubov
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23536
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23536.patch

Introduce a new vqe_amf filter implementing AMD AMF Video Quality Enhancer.

The filter exposes VQ enhancement functionality through the attenuation option.

At present, the filter is available on Windows systems only.

Examples:
_ffmpeg -hwaccel amf -hwaccel_output_format amf -i input.mp4 -vf 
vqe_amf=attenuation=0.4 -c:v hevc_amf output.mp4_

_ffmpeg -init_hw_device d3d11va=dx11 -init_hw_device amf=hw@dx11 
-filter_hw_device hw -i input.mp4 -vf vqe_amf=attenuation=0.4 -c:v hevc_amf 
output.mp4_


>From 70e560eb05e76a4338b008789e26cd5440c4eb07 Mon Sep 17 00:00:00 2001
From: Araz Iusubov <[email protected]>
Date: Fri, 19 Jun 2026 17:19:37 +0200
Subject: [PATCH] avfilter/vf_vqe_amf: Add AMF Video Quality Enhancer filter

---
 Changelog                |   2 +-
 configure                |   1 +
 doc/filters.texi         |  37 +++++++++
 libavfilter/Makefile     |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/vf_vqe_amf.c | 169 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 210 insertions(+), 1 deletion(-)
 create mode 100644 libavfilter/vf_vqe_amf.c

diff --git a/Changelog b/Changelog
index 2ad3ee255f..6f54ca07d7 100644
--- a/Changelog
+++ b/Changelog
@@ -18,7 +18,7 @@ version <next>:
 - Remove ogg/celt parsing
 - Bitstream filter to split Dolby Vision multi-layer HEVC
 - Add AMF hardware memory mapping support.
-
+- Add AMF Video Quality Enhancer (vf_vqe_amf) filter
 
 version 8.1:
 - ffprobe -codec option
diff --git a/configure b/configure
index 5149f3c217..e4de18171d 100755
--- a/configure
+++ b/configure
@@ -4272,6 +4272,7 @@ scale_filter_deps="swscale"
 sr_amf_filter_deps="amf"
 vpp_amf_filter_deps="amf"
 frc_amf_filter_deps="amf windows_h"
+vqe_amf_filter_deps="amf windows_h"
 scale_qsv_filter_deps="libmfx"
 scale_qsv_filter_select="qsvvpp"
 scdet_filter_select="scene_sad"
diff --git a/doc/filters.texi b/doc/filters.texi
index 2cae41c7c5..63b4fcf1ab 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -14816,6 +14816,43 @@ Boolean value: enable dependency on future frame, 
improves quality for the cost
 of latency (Default value: enabled).
 @end table
 
+@section vqe_amf
+
+AMD AMF VQ Enhancer filter.
+This filter applies AMD AMF VQ Enhancement to the input video.
+
+This filter accepts the following option:
+
+@table @option
+
+@item attenuation
+Set VQ Enhancer strength. Allowed range is from @code{0.02} to @code{0.4}.
+Default is @code{0.1}.
+
+@item engine_type
+Set AMF memory type used by the filter.
+
+Possible values:
+
+@table @samp
+@item dx11
+DirectX 11
+@item dx12
+DirectX 12
+@item vulkan
+Vulkan
+@item opencl
+OpenCL
+@end table
+
+@end table
+
+Example:
+
+@example
+ffmpeg -i input.mp4 -vf vqe_amf=attenuation=0.4 -c:v hevc_amf output.mp4
+@end example
+
 @section framestep
 
 Select one frame every N-th frame.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 5f0760a2ff..ae7da8b068 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -576,6 +576,7 @@ OBJS-$(CONFIG_VIGNETTE_FILTER)               += 
vf_vignette.o
 OBJS-$(CONFIG_VMAFMOTION_FILTER)             += vf_vmafmotion.o framesync.o
 OBJS-$(CONFIG_VPP_AMF_FILTER)                += vf_vpp_amf.o scale_eval.o 
vf_amf_common.o
 OBJS-$(CONFIG_FRC_AMF_FILTER)                += vf_frc_amf.o vf_amf_common.o
+OBJS-$(CONFIG_VQE_AMF_FILTER)                += vf_vqe_amf.o vf_amf_common.o
 OBJS-$(CONFIG_VPP_QSV_FILTER)                += vf_vpp_qsv.o
 OBJS-$(CONFIG_VSTACK_FILTER)                 += vf_stack.o framesync.o
 OBJS-$(CONFIG_W3FDIF_FILTER)                 += vf_w3fdif.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 66c49d453b..a56ca79f8f 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -444,6 +444,7 @@ extern const FFFilter ff_vf_scale;
 extern const FFFilter ff_vf_vpp_amf;
 extern const FFFilter ff_vf_sr_amf;
 extern const FFFilter ff_vf_frc_amf;
+extern const FFFilter ff_vf_vqe_amf;
 extern const FFFilter ff_vf_scale_cuda;
 extern const FFFilter ff_vf_scale_d3d11;
 extern const FFFilter ff_vf_scale_d3d12;
diff --git a/libavfilter/vf_vqe_amf.c b/libavfilter/vf_vqe_amf.c
new file mode 100644
index 0000000000..d7249d999b
--- /dev/null
+++ b/libavfilter/vf_vqe_amf.c
@@ -0,0 +1,169 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Quality Enhancer video filter with AMF hardware acceleration
+ */
+
+#include "libavutil/opt.h"
+
+#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_amf.h"
+#include "libavutil/hwcontext_amf_internal.h"
+
+#include "AMF/components/VQEnhancer.h"
+#include "vf_amf_common.h"
+
+#include "avfilter.h"
+#include "avfilter_internal.h"
+#include "formats.h"
+#include "video.h"
+
+#if CONFIG_D3D11VA
+#include <d3d11.h>
+#endif
+
+#if CONFIG_D3D12VA
+#include <d3d12.h>
+#endif
+
+typedef struct AMFVQEFilterContext {
+    AMFFilterContext common;
+
+    int engine_type;
+    double attenuation;
+} AMFVQEFilterContext;
+
+static int amf_vqe_init(AVFilterContext *avctx) {
+    AMFVQEFilterContext *ctx = avctx->priv;
+
+    ctx->common.format = AV_PIX_FMT_NONE;
+
+    return 0;
+}
+
+static int amf_filter_query_formats(AVFilterContext *avctx)
+{
+    const enum AVPixelFormat *output_pix_fmts;
+    static const enum AVPixelFormat input_pix_fmts[] = {
+        AV_PIX_FMT_AMF_SURFACE,
+        AV_PIX_FMT_NV12,
+        AV_PIX_FMT_P010,
+        AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_RGBAF16,
+        AV_PIX_FMT_X2BGR10,
+        AV_PIX_FMT_NONE,
+    };
+    static const enum AVPixelFormat output_pix_fmts_default[] = {
+        AV_PIX_FMT_AMF_SURFACE,
+        AV_PIX_FMT_NV12,
+        AV_PIX_FMT_P010,
+        AV_PIX_FMT_BGRA,
+        AV_PIX_FMT_RGBA,
+        AV_PIX_FMT_RGBAF16,
+        AV_PIX_FMT_X2BGR10,
+        AV_PIX_FMT_NONE,
+    };
+    output_pix_fmts = output_pix_fmts_default;
+
+    return amf_setup_input_output_formats(avctx, input_pix_fmts, 
output_pix_fmts);
+}
+
+static int amf_vqe_filter_config_output(AVFilterLink *outlink)
+{
+    AVFilterContext     *avctx = outlink->src;
+    AMFComponent        *amf_filter = NULL;
+    AVFilterLink        *inlink = avctx->inputs[0];
+    AMFVQEFilterContext *vqe_ctx = avctx->priv;
+    AMFFilterContext    *amf_ctx = &vqe_ctx->common;
+    AVAMFDeviceContext  *device_ctx = NULL;
+
+    int err;
+    AMF_RESULT res;
+    enum AVPixelFormat in_format;
+
+    err = amf_init_filter_config(outlink, &in_format);
+    if (err < 0)
+        return err;
+
+    device_ctx = amf_ctx->amf_device_ctx;
+
+    res = AMF_IFACE_CALL(device_ctx->factory, CreateComponent, 
device_ctx->context, AMFVQEnhancer, &amf_ctx->component);
+    AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_FILTER_NOT_FOUND, 
"CreateComponent(%ls) failed with error %d\n", AMFVQEnhancer, res);
+
+    amf_filter = amf_ctx->component;
+
+    if (vqe_ctx->engine_type != -1)
+        AMF_ASSIGN_PROPERTY_INT64(res, amf_filter, 
AMF_VIDEO_ENHANCER_ENGINE_TYPE, vqe_ctx->engine_type);
+
+    AMF_ASSIGN_PROPERTY_DOUBLE(res, amf_filter, AMF_VE_FCR_ATTENUATION, 
vqe_ctx->attenuation);
+    AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, "Failed to set 
VQ enhancer attenuation: %d\n", res);
+
+    res = AMF_IFACE_CALL(amf_filter, Init, av_av_to_amf_format(in_format), 
inlink->w, inlink->h);
+    AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"AMFVQEnhancer-Init() failed with error %d\n", res);
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(AMFVQEFilterContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption vqe_amf_options[] = {
+    { "engine_type",    "Engine type",   OFFSET(engine_type), AV_OPT_TYPE_INT, 
{ .i64 = -1 }, -1, AMF_MEMORY_OPENCL, .flags = FLAGS, "engine_type" },
+    { "dx11",           "DirectX 11",    0,  AV_OPT_TYPE_CONST,   { .i64 = 
AMF_MEMORY_DX11 }, 0, 0, FLAGS, "engine_type" },
+    { "dx12",           "DirectX 12",    0,  AV_OPT_TYPE_CONST,   { .i64 = 
AMF_MEMORY_DX12 }, 0, 0, FLAGS, "engine_type" },
+    { "vulkan",         "Vulkan",        0,  AV_OPT_TYPE_CONST,   { .i64 = 
AMF_MEMORY_VULKAN }, 0, 0, FLAGS, "engine_type" },
+    { "opencl",         "OpenCL",        0,  AV_OPT_TYPE_CONST,   { .i64 = 
AMF_MEMORY_OPENCL }, 0, 0, FLAGS, "engine_type" },
+
+    { "attenuation",    "Control VQEnhancer strength", OFFSET(attenuation), 
AV_OPT_TYPE_DOUBLE,  { .dbl = 0.1  },  0.02, 0.4, FLAGS, "attenuation" },
+
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(vqe_amf);
+
+static const AVFilterPad amf_filter_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = amf_filter_filter_frame,
+    }
+};
+
+static const AVFilterPad amf_filter_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = amf_vqe_filter_config_output,
+    }
+};
+
+FFFilter ff_vf_vqe_amf = {
+    .p.name         = "vqe_amf",
+    .p.description  = NULL_IF_CONFIG_SMALL("AMD AMF VQ Enhancer"),
+    .p.priv_class   = &vqe_amf_class,
+    .p.flags        = AVFILTER_FLAG_HWDEVICE,
+    .priv_size      = sizeof(AMFVQEFilterContext),
+    .init           = amf_vqe_init,
+    .uninit         = amf_filter_uninit,
+    FILTER_INPUTS(amf_filter_inputs),
+    FILTER_OUTPUTS(amf_filter_outputs),
+    FILTER_QUERY_FUNC(&amf_filter_query_formats),
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
+};
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to