This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 35660a244de7b9a26bbaaf2cd2bd2ab95d3169c7 Author: Julius Bairaktaris <[email protected]> AuthorDate: Mon Aug 31 16:08:25 2026 +0200 Commit: ArazIusubov <[email protected]> CommitDate: Wed Sep 16 22:05:28 2026 +0000 avfilter/amf: advertise only AMF surfaces on the output link amf_init_filter_config() always creates an AV_PIX_FMT_AMF_SURFACE frames context and amf_amfsurface_to_avframe() allocates every output frame from it, so an AMF filter returns an AMF surface no matter what the output link negotiated. The output format lists offered software formats and, for a D3D11VA or DXVA2 device, the foreign hardware format, so a downstream filter that takes one of them made the link agree on a format the filter never produces: ffmpeg -f lavfi -i testsrc2,format=nv12 \ -vf vpp_amf=w=320:h=180:format=nv12,signalstats -f null - crashes, because signalstats reads an AMFSurface pointer as an NV12 plane. The frame carries the right format, so it is only the link that lies, but nothing downstream looks at that. Offer AV_PIX_FMT_AMF_SURFACE alone, which is what the hardware filters in the tree do. A software consumer now needs an explicit hwdownload, which was already the only way to get a correct software frame out of these filters, and negotiation fails at configuration time instead of handing out a mislabelled surface. The device type still selects the input format, where D3D11 and DXVA2 surfaces really are what the filter is handed. The documentation examples and the sr_amf note on the zeroed alpha channel followed the filter with a software format directly, which no longer forms a valid chain; they now name the download and the frames context format first. Tested on Windows 11, RX 9070 XT, driver 32.0.31041.1004: the case above now fails to configure instead of crashing, and vpp_amf, vqe_amf, frc_amf and sr_amf keep working with software, AMF, D3D11VA and DXVA2 input, into hwdownload and into h264_amf and hevc_amf. Assisted-by: Claude Opus 5 Assisted-by: Claude Fable 5.1 Signed-off-by: Julius Bairaktaris <[email protected]> --- doc/filters.texi | 15 ++++++++++----- libavfilter/vf_amf_common.c | 9 +++++---- libavfilter/vf_amf_common.h | 2 +- libavfilter/vf_frc_amf.c | 14 +------------- libavfilter/vf_sr_amf.c | 29 +++++++---------------------- libavfilter/vf_vpp_amf.c | 13 +------------ libavfilter/vf_vqe_amf.c | 10 +--------- 7 files changed, 26 insertions(+), 66 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 070df58779..0407c46917 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -23286,8 +23286,9 @@ DirectX 12 device, so it is available on Windows only. Inputs in other formats such as @code{nv12} or @code{p010} are converted to a packed RGB format automatically. Note that the VideoSR algorithms (@code{sr1-0} and @code{sr1-1}) do not -preserve the alpha channel (it is left zeroed); append e.g. @code{format=rgb24} -downstream if an opaque result is required. +preserve the alpha channel (it is left zeroed); drop it after the download, +e.g. with @code{hwdownload,format=rgba,format=rgb24}, if an opaque result is +required. @end table @@ -23322,9 +23323,11 @@ which does not fill the entire output surface should be filled with a solid colo @itemize @item -Scale input to 720p, keeping aspect ratio and ensuring the output is yuv420p. +Upscale to 720p, keeping aspect ratio, and read the result back into system +memory. The filter always outputs AMF surfaces, so a @ref{hwdownload} is needed +to feed a software encoder. @example -sr_amf=-2:720:format=yuv420p +sr_amf=-2:720,hwdownload,format=nv12 @end example @item @@ -26228,8 +26231,10 @@ JEDEC P22 phosphors @itemize @item Scale input to 720p, keeping aspect ratio and ensuring the output is yuv420p. +The filter always outputs AMF surfaces, so a @ref{hwdownload} is needed to feed a +software encoder. @example -vpp_amf=-2:720:format=yuv420p +vpp_amf=-2:720:format=yuv420p,hwdownload,format=yuv420p @end example @item diff --git a/libavfilter/vf_amf_common.c b/libavfilter/vf_amf_common.c index 2d70d6d954..b3a18ed9b1 100644 --- a/libavfilter/vf_amf_common.c +++ b/libavfilter/vf_amf_common.c @@ -221,12 +221,15 @@ fail: int amf_setup_input_output_formats(AVFilterContext *avctx, - const enum AVPixelFormat *input_pix_fmts, - const enum AVPixelFormat *output_pix_fmts) + const enum AVPixelFormat *input_pix_fmts) { int err; AVFilterFormats *input_formats; AVFilterFormats *output_formats; + static const enum AVPixelFormat output_pix_fmts[] = { + AV_PIX_FMT_AMF_SURFACE, + AV_PIX_FMT_NONE, + }; //in case if hw_device_ctx is set to DXVA2 we change order of pixel formats to set DXVA2 be chosen by default //The order is ignored if hw_frames_ctx is not NULL on the config_output stage @@ -242,7 +245,6 @@ int amf_setup_input_output_formats(AVFilterContext *avctx, AV_PIX_FMT_NONE, }; input_pix_fmts = pix_fmts_d3d11; - output_pix_fmts = pix_fmts_d3d11; } break; #endif @@ -254,7 +256,6 @@ int amf_setup_input_output_formats(AVFilterContext *avctx, AV_PIX_FMT_NONE, }; input_pix_fmts = pix_fmts_dxva2; - output_pix_fmts = pix_fmts_dxva2; } break; #endif diff --git a/libavfilter/vf_amf_common.h b/libavfilter/vf_amf_common.h index eedaef7ba6..4910b23e9b 100644 --- a/libavfilter/vf_amf_common.h +++ b/libavfilter/vf_amf_common.h @@ -79,7 +79,7 @@ int amf_copy_surface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface* s void amf_free_amfsurface(void *opaque, uint8_t *data); AVFrame *amf_amfsurface_to_avframe(AVFilterContext *avctx, AMFSurface* pSurface); int amf_avframe_to_amfsurface(AVFilterContext *avctx, const AVFrame *frame, AMFSurface** ppSurface); -int amf_setup_input_output_formats(AVFilterContext *avctx, const enum AVPixelFormat *input_pix_fmts, const enum AVPixelFormat *output_pix_fmts); +int amf_setup_input_output_formats(AVFilterContext *avctx, const enum AVPixelFormat *input_pix_fmts); int amf_filter_filter_frame(AVFilterLink *inlink, AVFrame *in); #endif /* AVFILTER_AMF_COMMON_H */ diff --git a/libavfilter/vf_frc_amf.c b/libavfilter/vf_frc_amf.c index 1a84a2ee4f..c05ab818e8 100644 --- a/libavfilter/vf_frc_amf.c +++ b/libavfilter/vf_frc_amf.c @@ -67,7 +67,6 @@ static int amf_frc_init(AVFilterContext *avctx) { 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_D3D11, @@ -80,19 +79,8 @@ static int amf_filter_query_formats(AVFilterContext *avctx) 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); + return amf_setup_input_output_formats(avctx, input_pix_fmts); } static int amf_frc_filter_config_output(AVFilterLink *outlink) diff --git a/libavfilter/vf_sr_amf.c b/libavfilter/vf_sr_amf.c index 8ecfcbb1fe..0d8ba40b31 100644 --- a/libavfilter/vf_sr_amf.c +++ b/libavfilter/vf_sr_amf.c @@ -68,7 +68,7 @@ static int amf_is_packed_rgb(enum AVPixelFormat format) static int amf_filter_query_formats(AVFilterContext *avctx) { AMFFilterContext *ctx = avctx->priv; - const enum AVPixelFormat *input_pix_fmts, *output_pix_fmts; + const enum AVPixelFormat *input_pix_fmts; static const enum AVPixelFormat input_pix_fmts_default[] = { AV_PIX_FMT_NV12, AV_PIX_FMT_P010, @@ -80,17 +80,6 @@ static int amf_filter_query_formats(AVFilterContext *avctx) AV_PIX_FMT_RGBAF16, AV_PIX_FMT_NONE, }; - static const enum AVPixelFormat output_pix_fmts_default[] = { - AV_PIX_FMT_NV12, - AV_PIX_FMT_P010, - AV_PIX_FMT_BGRA, - AV_PIX_FMT_RGBA, - AV_PIX_FMT_AMF_SURFACE, - AV_PIX_FMT_D3D11, - AV_PIX_FMT_DXVA2_VLD, - AV_PIX_FMT_RGBAF16, - AV_PIX_FMT_NONE, - }; // sr1-1 and point need packed RGB; YUV is converted on the GPU static const enum AVPixelFormat pix_fmts_packed_rgb[] = { AV_PIX_FMT_RGBA, @@ -111,26 +100,22 @@ static int amf_filter_query_formats(AVFilterContext *avctx) }; int i; - if (amf_hq_scaler_needs_packed_rgb(ctx->algorithm)) { - input_pix_fmts = pix_fmts_packed_rgb; - output_pix_fmts = pix_fmts_packed_rgb; - } else { - input_pix_fmts = input_pix_fmts_default; - output_pix_fmts = output_pix_fmts_default; - } + if (amf_hq_scaler_needs_packed_rgb(ctx->algorithm)) + input_pix_fmts = pix_fmts_packed_rgb; + else + input_pix_fmts = input_pix_fmts_default; if (ctx->format_opt != AV_PIX_FMT_NONE) { for (i = 0; input_pix_fmts[i] != AV_PIX_FMT_NONE; i++) { if (input_pix_fmts[i] == ctx->format_opt) { pix_fmts_requested[0] = ctx->format_opt; - input_pix_fmts = pix_fmts_requested; - output_pix_fmts = pix_fmts_requested; + input_pix_fmts = pix_fmts_requested; break; } } } - return amf_setup_input_output_formats(avctx, input_pix_fmts, output_pix_fmts); + return amf_setup_input_output_formats(avctx, input_pix_fmts); } static int amf_filter_config_output(AVFilterLink *outlink) diff --git a/libavfilter/vf_vpp_amf.c b/libavfilter/vf_vpp_amf.c index f9ed2dc635..970bb770a1 100644 --- a/libavfilter/vf_vpp_amf.c +++ b/libavfilter/vf_vpp_amf.c @@ -46,7 +46,6 @@ 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_D3D11, @@ -58,18 +57,8 @@ static int amf_filter_query_formats(AVFilterContext *avctx) AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, }; - static const enum AVPixelFormat output_pix_fmts_default[] = { - AV_PIX_FMT_AMF_SURFACE, - AV_PIX_FMT_D3D11, - AV_PIX_FMT_DXVA2_VLD, - AV_PIX_FMT_NV12, - AV_PIX_FMT_BGRA, - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NONE, - }; - output_pix_fmts = output_pix_fmts_default; - return amf_setup_input_output_formats(avctx, input_pix_fmts, output_pix_fmts); + return amf_setup_input_output_formats(avctx, input_pix_fmts); } static int amf_filter_config_output(AVFilterLink *outlink) diff --git a/libavfilter/vf_vqe_amf.c b/libavfilter/vf_vqe_amf.c index 63febf5c15..e36492645d 100644 --- a/libavfilter/vf_vqe_amf.c +++ b/libavfilter/vf_vqe_amf.c @@ -62,7 +62,6 @@ static int amf_vqe_init(AVFilterContext *avctx) { 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_D3D11, @@ -71,15 +70,8 @@ static int amf_filter_query_formats(AVFilterContext *avctx) AV_PIX_FMT_P010, 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_NONE, - }; - output_pix_fmts = output_pix_fmts_default; - return amf_setup_input_output_formats(avctx, input_pix_fmts, output_pix_fmts); + return amf_setup_input_output_formats(avctx, input_pix_fmts); } static int amf_vqe_filter_config_output(AVFilterLink *outlink) -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
