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

Note: at the moment the filter is available only for Windows, Linux support 
will be added soon.


>From cf8d2c3ad8cdb32d170cdd9fd86c38d2149899a5 Mon Sep 17 00:00:00 2001
From: Dmitrii Gershenkop <[email protected]>
Date: Mon, 23 Mar 2026 17:56:18 +0100
Subject: [PATCH] avfilter/vf_frc_amf: Add AMF Frame Rate Converter filter

---
 Changelog                   |   1 +
 configure                   |   1 +
 doc/filters.texi            |  66 +++++++++
 libavfilter/Makefile        |   1 +
 libavfilter/allfilters.c    |   1 +
 libavfilter/version.h       |   2 +-
 libavfilter/vf_amf_common.c |  20 ++-
 libavfilter/vf_amf_common.h |   2 +-
 libavfilter/vf_frc_amf.c    | 262 ++++++++++++++++++++++++++++++++++++
 libavfilter/vf_frc_amf.h    |  38 ++++++
 libavfilter/vf_sr_amf.c     |   2 +-
 libavfilter/vf_vpp_amf.c    |   4 +-
 12 files changed, 387 insertions(+), 13 deletions(-)
 create mode 100644 libavfilter/vf_frc_amf.c
 create mode 100644 libavfilter/vf_frc_amf.h

diff --git a/Changelog b/Changelog
index a4241958bc..822d170db0 100644
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,7 @@ releases are sorted from youngest to oldest.
 version <next>:
 - Extend AMF Color Converter (vf_vpp_amf) HDR capabilities
 - LCEVC track muxing support in MP4 muxer
+- Add AMF Frame Rate Converter (vf_frc_amf) filter
 
 
 version 8.1:
diff --git a/configure b/configure
index 8f9fb04115..0be12b4f7b 100755
--- a/configure
+++ b/configure
@@ -4206,6 +4206,7 @@ scale2ref_filter_deps="swscale"
 scale_filter_deps="swscale"
 sr_amf_filter_deps="amf"
 vpp_amf_filter_deps="amf"
+frc_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 973a93345d..c3551a91f7 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -14749,6 +14749,72 @@ This flag is enabled by default.
 @end table
 @end table
 
+@section frc_amf
+
+Double the frame rate, using Frame Rate Converter (FRC) provided by
+AMD Advanced Media Framework library for hardware acceleration.
+
+The filter accepts the following options:
+
+@table @option
+@item engine_type
+Specify the engine used to run shaders.
+@table @samp
+@item dx11
+DirectX 11.
+
+@item dx12
+DirectX 12 (Default value).
+@end table
+
+@item enable
+Boolean value: enable/disable FRC. (Default value: enabled).
+
+@item fallback_mode
+Fallback behavior in case of low interpolation confidence.
+@table @samp
+@item duplicate
+Duplicate frame.
+
+@item blend
+Blend two frames together (Default value).
+@end table
+
+@item indicator
+Boolean value: show FRC indicator square in the top right corner of the video
+(Default value: disabled).
+
+@item profile
+Level of hierarchical motion search.
+@table @samp
+@item low
+Less levels of hierarchical motion search.
+Only recommended for extremely low resolutions.
+
+@item high
+Recommended for any resolution up to 1440p. (Default value)
+
+@item super
+More levels of hierarchical motion search. Recommended for resolutions 1440p
+or higher.
+@end table
+
+@item mv_search_mode
+Performance mode of the motion search.
+@table @samp
+@item native
+Conduct motion search on the full resolution of source images.
+
+@item performance
+Conduct motion search on the down scaled source images.
+Recommended for APU or low end GPU for better performance.
+@end table
+
+@item use_future_frame
+Boolean value: enable dependency on future frame, improves quality for the cost
+of latency (Default value: enabled).
+@end table
+
 @section framestep
 
 Select one frame every N-th frame.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index a530cfae29..ae994ecbd1 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -572,6 +572,7 @@ OBJS-$(CONFIG_VIF_FILTER)                    += vf_vif.o 
framesync.o
 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_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 e26859e159..f718533a3e 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -443,6 +443,7 @@ extern const FFFilter ff_vf_sab;
 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_scale_cuda;
 extern const FFFilter ff_vf_scale_d3d11;
 extern const FFFilter ff_vf_scale_d3d12;
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 4afd496e3f..b5ec9adb0a 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -32,7 +32,7 @@
 #include "version_major.h"
 
 #define LIBAVFILTER_VERSION_MINOR  15
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MICRO 102
 
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
diff --git a/libavfilter/vf_amf_common.c b/libavfilter/vf_amf_common.c
index 86b9d846cb..9f02520c6e 100644
--- a/libavfilter/vf_amf_common.c
+++ b/libavfilter/vf_amf_common.c
@@ -265,13 +265,12 @@ int amf_copy_surface(AVFilterContext *avctx, const 
AVFrame *frame,
     return 0;
 }
 
-int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat 
*in_format)
+int amf_init_filter_config(AVFilterLink *outlink, AMFFilterContext *ctx, enum 
AVPixelFormat *in_format)
 {
     int err;
     AMF_RESULT res;
     AVFilterContext *avctx = outlink->src;
     AVFilterLink   *inlink = avctx->inputs[0];
-    AMFFilterContext  *ctx = avctx->priv;
     AVHWFramesContext *hwframes_out;
     AVHWDeviceContext   *hwdev_ctx;
     enum AVPixelFormat in_sw_format = inlink->format;
@@ -280,11 +279,16 @@ int amf_init_filter_config(AVFilterLink *outlink, enum 
AVPixelFormat *in_format)
     FilterLink        *outl = ff_filter_link(outlink);
     double w_adj = 1.0;
 
-    if ((err = ff_scale_eval_dimensions(avctx,
-                                        ctx->w_expr, ctx->h_expr,
-                                        inlink, outlink,
-                                        &ctx->width, &ctx->height)) < 0)
-        return err;
+    if (ctx->w_expr && ctx->h_expr) {
+        if ((err = ff_scale_eval_dimensions(avctx,
+                                            ctx->w_expr, ctx->h_expr,
+                                            inlink, outlink,
+                                            &ctx->width, &ctx->height)) < 0)
+            return err;
+    } else {
+        ctx->width = inlink->w;
+        ctx->height = inlink->h;
+    }
 
     if (ctx->reset_sar && inlink->sample_aspect_ratio.num)
         w_adj = (double) inlink->sample_aspect_ratio.num / 
inlink->sample_aspect_ratio.den;
@@ -445,6 +449,8 @@ AVFrame *amf_amfsurface_to_avframe(AVFilterContext *avctx, 
AMFSurface* pSurface)
         }
     }
 
+    frame->pts = pSurface->pVtbl->GetPts(pSurface);
+
     return frame;
 }
 
diff --git a/libavfilter/vf_amf_common.h b/libavfilter/vf_amf_common.h
index 0290a52c45..adcb2311ab 100644
--- a/libavfilter/vf_amf_common.h
+++ b/libavfilter/vf_amf_common.h
@@ -70,7 +70,7 @@ typedef struct AMFFilterContext {
 
 int amf_filter_init(AVFilterContext *avctx);
 void amf_filter_uninit(AVFilterContext *avctx);
-int amf_init_filter_config(AVFilterLink *outlink, enum AVPixelFormat 
*in_format);
+int amf_init_filter_config(AVFilterLink *outlink, AMFFilterContext *ctx, enum 
AVPixelFormat *in_format);
 int amf_copy_surface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface* 
surface);
 void amf_free_amfsurface(void *opaque, uint8_t *data);
 AVFrame *amf_amfsurface_to_avframe(AVFilterContext *avctx, AMFSurface* 
pSurface);
diff --git a/libavfilter/vf_frc_amf.c b/libavfilter/vf_frc_amf.c
new file mode 100644
index 0000000000..b39a91ba55
--- /dev/null
+++ b/libavfilter/vf_frc_amf.c
@@ -0,0 +1,262 @@
+/*
+ * 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
+ * Video Frame Rate Converter filter with AMF hardware acceleration
+ */
+
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+
+#include "avfilter_internal.h"
+
+#include "vf_frc_amf.h"
+#include "AMF/components/FRC.h"
+#include "libavutil/hwcontext_amf_internal.h"
+
+#if CONFIG_D3D11VA
+#include <d3d11.h>
+#endif
+
+#if CONFIG_D3D12VA
+#include <d3d12.h>
+#endif
+
+static int amf_frc_init(AVFilterContext *avctx) {
+    AMFFRCFilterContext *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_frc_filter_config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *avctx = outlink->src;
+    AVFilterLink    *inlink = avctx->inputs[0];
+    FilterLink      *il = ff_filter_link(inlink);
+    FilterLink      *ol = ff_filter_link(outlink);
+    AMFFRCFilterContext  *ctx = avctx->priv;
+
+    int err;
+    AMF_RESULT res;
+    enum AVPixelFormat in_format;
+
+    err = amf_init_filter_config(outlink, &ctx->common, &in_format);
+    if (err < 0)
+        return err;
+
+    res = 
ctx->common.amf_device_ctx->factory->pVtbl->CreateComponent(ctx->common.amf_device_ctx->factory,
 ctx->common.amf_device_ctx->context, AMFFRC, &ctx->common.component);
+    AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_FILTER_NOT_FOUND, 
"CreateComponent(%ls) failed with error %d\n", AMFFRC, res);
+
+    outlink->time_base = inlink->time_base;
+    ol->frame_rate = il->frame_rate;
+    ol->frame_rate.num *= 2;
+    // Possible bug: FRC must start enabled to be toggleable after init.
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_MODE, 
FRC_x2_PRESENT);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_ENGINE_TYPE, 
ctx->engine_type);
+    AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"AMFFRC->SetProperty(%ls) failed with error %d\n", AMF_FRC_ENGINE_TYPE, res);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, 
AMF_FRC_ENABLE_FALLBACK, ctx->fallback);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_INDICATOR, 
ctx->indicator);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_PROFILE, 
ctx->profile);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, 
AMF_FRC_MV_SEARCH_MODE, ctx->mv_search_mode);
+
+    AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, 
AMF_FRC_USE_FUTURE_FRAME, ctx->use_future_frame);
+
+    res = ctx->common.component->pVtbl->Init(ctx->common.component, 
av_av_to_amf_format(in_format), inlink->w, inlink->h);
+    AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"AMFConverter-Init() failed with error %d\n", res);
+
+    return 0;
+}
+
+#define OFFSET(x) offsetof(AMFFRCFilterContext, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption frc_amf_options[] = {
+    { "engine_type",    "Engine type",   OFFSET(engine_type), AV_OPT_TYPE_INT, 
{ .i64 = FRC_ENGINE_DX12 }, FRC_ENGINE_DX12, FRC_ENGINE_DX11, .flags = FLAGS, 
"engine_type" },
+    { "dx11",           "DirectX 11",    0,  AV_OPT_TYPE_CONST,   { .i64 = 
FRC_ENGINE_DX11 }, 0, 0, FLAGS, "engine_type" },
+    { "dx12",           "DirectX 12",    0,  AV_OPT_TYPE_CONST,   { .i64 = 
FRC_ENGINE_DX12 }, 0, 0, FLAGS, "engine_type" },
+
+    { "enable",         "Enable FRC", OFFSET(enable), AV_OPT_TYPE_BOOL, { .i64 
= 1 }, 0, 1, .flags = FLAGS },
+
+    { "fallback_mode",  "Fallback behavior in case of low interpolation 
confidence", OFFSET(fallback), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, .flags = 
FLAGS, "fallback_mode" },
+    { "duplicate",      "Duplicate frame",           0,  AV_OPT_TYPE_CONST, { 
.i64 = 0 }, 0, 0, FLAGS, "fallback_mode" },
+    { "blend",          "Blend two frames together", 0,  AV_OPT_TYPE_CONST, { 
.i64 = 1 }, 0, 0, FLAGS, "fallback_mode" },
+
+    { "indicator",      "Show FRC indicator square in the top right corner of 
the video.", OFFSET(indicator), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = 
FLAGS },
+
+    { "profile",        "Level of hierarchical motion search",  
OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FRC_PROFILE_HIGH }, FRC_PROFILE_LOW, 
FRC_PROFILE_SUPER, FLAGS, "profile" },
+    { "low",            "Less levels of hierarchical motion search. "
+                        "Only recommended for extremely low resolutions.",  0, 
 AV_OPT_TYPE_CONST, { .i64 = FRC_PROFILE_LOW },    0, 0, FLAGS, "profile" },
+    { "high",           "Recommended for any resolution up to 1440p.",      0, 
 AV_OPT_TYPE_CONST, { .i64 = FRC_PROFILE_HIGH },   0, 0, FLAGS, "profile" },
+    { "super",          "More levels of hierarchical motion search. "
+                        "Recommended for resolutions 1440p or higher.",     0, 
 AV_OPT_TYPE_CONST, { .i64 = FRC_PROFILE_SUPER },  0, 0, FLAGS, "profile" },
+
+    { "mv_search_mode", "Performance mode of the motion search",  
OFFSET(mv_search_mode), AV_OPT_TYPE_INT,   { .i64 = FRC_MV_SEARCH_NATIVE }, 
FRC_MV_SEARCH_NATIVE, FRC_MV_SEARCH_PERFORMANCE, FLAGS, "mv_search_mode" },
+    { "native",         "Conduct motion search on the full resolution of 
source images.",  0, AV_OPT_TYPE_CONST, { .i64 = FRC_MV_SEARCH_NATIVE },       
0, 0, FLAGS, "mv_search_mode" },
+    { "performance",    "Conduct motion search on the down scaled source 
images. "
+                        "Recommended for APU or low end GPU for better 
performance.",      0, AV_OPT_TYPE_CONST, { .i64 = FRC_MV_SEARCH_PERFORMANCE }, 
 0, 0, FLAGS, "mv_search_mode" },
+
+    { "use_future_frame", "Enable dependency on future frame, improves quality 
for the cost of latency", OFFSET(use_future_frame), AV_OPT_TYPE_BOOL, { .i64 = 
1 }, 0, 1, .flags = FLAGS },
+
+    { NULL },
+};
+
+AVFILTER_DEFINE_CLASS(frc_amf);
+
+static int amf_frc_filter_avframe(AVFilterLink *inlink, AVFrame *in)
+{
+    AVFilterContext  *avctx = inlink->dst;
+    AMFFRCFilterContext *ctx = avctx->priv;
+    AVFilterLink     *outlink = avctx->outputs[0];
+    AMFSurface       *surface_out = NULL;
+    AMFSurface       *surface_in = NULL;
+    FilterLink       *il = ff_filter_link(inlink);
+    FilterLink       *ol = ff_filter_link(outlink);
+    AMF_RESULT       res = AMF_FAIL;
+    AMFData          *data_out = NULL;
+    AVFrame          *out = NULL;
+    int              ret = 0;
+
+    if (!ctx->common.component)
+        return AVERROR(EINVAL);
+
+    ret = amf_avframe_to_amfsurface(avctx, in, &surface_in);
+    if (ret < 0)
+        goto fail;
+
+    if (ctx->enable) {
+        AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_MODE, 
FRC_x2_PRESENT);
+        ol->frame_rate.num = il->frame_rate.num * 2;
+    } else {
+        AMF_ASSIGN_PROPERTY_INT64(res, ctx->common.component, AMF_FRC_MODE, 
FRC_OFF);
+        ol->frame_rate.num = il->frame_rate.num;
+    }
+    AMF_GOTO_FAIL_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"SubmitInput(): Failed to %s FRC, error:%d\n", ctx->enable ? "enable" : 
"disable", res);
+
+    res = ctx->common.component->pVtbl->SubmitInput(ctx->common.component, 
(AMFData*)surface_in);
+    surface_in->pVtbl->Release(surface_in);
+    surface_in = NULL;
+    AMF_GOTO_FAIL_IF_FALSE(avctx, (res == AMF_OK || res == AMF_INPUT_FULL), 
AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res);
+
+    while (true) {
+        res = ctx->common.component->pVtbl->QueryOutput(ctx->common.component, 
&data_out);
+
+        AMF_GOTO_FAIL_IF_FALSE(avctx, (res == AMF_OK || res == AMF_REPEAT), 
AVERROR_UNKNOWN, "QueryOutput() failed with error %d\n", res);
+        if (data_out == NULL)
+            break;
+
+        AMFGuid guid = IID_AMFSurface();
+        res = data_out->pVtbl->QueryInterface(data_out, &guid, 
(void**)&surface_out);
+        data_out->pVtbl->Release(data_out);
+        data_out = NULL;
+        AMF_RETURN_IF_FALSE(avctx, res == AMF_OK, AVERROR_UNKNOWN, 
"QueryInterface(IID_AMFSurface) failed with error %d\n", res);
+
+        out = amf_amfsurface_to_avframe(avctx, surface_out);
+        AMF_GOTO_FAIL_IF_FALSE(avctx, out != NULL, AVERROR(ENOMEM), "Failed to 
convert AMFSurface to AVFrame\n");
+
+        ret = av_frame_copy_props(out, in);
+        AMF_GOTO_FAIL_IF_FALSE(avctx, ret >= 0, AVERROR(ENOMEM), "Failed to 
copy frame properties\n");
+
+        if (ctx->enable)
+            out->duration /= 2;
+
+        out->hw_frames_ctx = av_buffer_ref(ctx->common.hwframes_out_ref);
+        if (!out->hw_frames_ctx) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        ret = ff_filter_frame(outlink, out);
+        out = NULL;
+        if (ret < 0)
+            goto fail;
+    }
+
+fail:
+    av_frame_unref(in);
+    av_frame_free(&in);
+    if (out != NULL)
+        av_frame_free(&out);
+
+    return ret;
+}
+
+static const AVFilterPad amf_filter_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = amf_frc_filter_avframe,
+    }
+};
+
+
+static const AVFilterPad amf_filter_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .config_props = amf_frc_filter_config_output,
+    }
+};
+
+FFFilter ff_vf_frc_amf = {
+    .p.name        = "frc_amf",
+    .p.description = NULL_IF_CONFIG_SMALL("AMF video Frame Rate Converter"),
+    .p.priv_class  = &frc_amf_class,
+    .p.flags       = AVFILTER_FLAG_HWDEVICE,
+    .priv_size     = sizeof(AMFFRCFilterContext),
+    .init          = amf_frc_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,
+};
\ No newline at end of file
diff --git a/libavfilter/vf_frc_amf.h b/libavfilter/vf_frc_amf.h
new file mode 100644
index 0000000000..5aa0e067c3
--- /dev/null
+++ b/libavfilter/vf_frc_amf.h
@@ -0,0 +1,38 @@
+/*
+ * 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
+ */
+
+#ifndef AVFILTER_AMF_FRC_H
+#define AVFILTER_AMF_FRC_H
+
+#include "vf_amf_common.h"
+
+typedef struct AMFFRCFilterContext {
+    AMFFilterContext common;
+
+    int engine_type;
+    int enable;
+    int fallback;
+    int indicator;
+    int profile;
+    int mv_search_mode;
+    int use_future_frame;
+
+} AMFFRCFilterContext;
+
+
+#endif /* AVFILTER_AMF_FRC_H */
\ No newline at end of file
diff --git a/libavfilter/vf_sr_amf.c b/libavfilter/vf_sr_amf.c
index 8f3ae7ed80..e3c33e7272 100644
--- a/libavfilter/vf_sr_amf.c
+++ b/libavfilter/vf_sr_amf.c
@@ -90,7 +90,7 @@ static int amf_filter_config_output(AVFilterLink *outlink)
     AMF_RESULT res;
     enum AVPixelFormat in_format;
 
-    err = amf_init_filter_config(outlink, &in_format);
+    err = amf_init_filter_config(outlink, ctx, &in_format);
     if (err < 0)
         return err;
 
diff --git a/libavfilter/vf_vpp_amf.c b/libavfilter/vf_vpp_amf.c
index 5d5955f4b2..19e429bd1c 100644
--- a/libavfilter/vf_vpp_amf.c
+++ b/libavfilter/vf_vpp_amf.c
@@ -91,10 +91,8 @@ static int amf_filter_config_output(AVFilterLink *outlink)
     const AVFrameSideData *sd;
     enum AMF_VIDEO_CONVERTER_COLOR_PROFILE_ENUM amf_color_profile;
     enum AVPixelFormat in_format;
-    const int chroma_den = 50000;
-    const int luma_den = 10000;
 
-    ret = amf_init_filter_config(outlink, &in_format);
+    ret = amf_init_filter_config(outlink, ctx, &in_format);
     if (ret < 0)
         return ret;
     // FIXME: add checks whether we have HW context
-- 
2.52.0

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

Reply via email to