PR #25561 opened by JuliusBairaktaris URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25561 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25561.patch
With AMF-surface output (`-hwaccel amf -hwaccel_output_format amf`), `amf_decode_init()` creates the frames context from `AMF_VIDEO_DECODER_OUTPUT_FORMAT`. When the decoder has not detected a format yet, it falls back to NV12. The context is only re-created on `AMF_RESOLUTION_CHANGED`, so it stays NV12 when the decoder then outputs P010 at the same size. The AV1 decoder doesn't report its format before decoding, even with a sequence header in the extradata, so every 10-bit AV1 stream comes out as P010 surfaces in an NV12 frames context, and `hwdownload,format=p010le` fails with `Failed to download frame: -22`. This patch re-creates the frames context, keeping its size, when an output surface's format differs from its `sw_format`. Tested on Windows 11, RX 9070 XT, driver 32.0.32015.7029: - 10-bit AV1 (raw OBU and Matroska) with AMF-surface output and `hwdownload,format=p010le` now decodes, with the same framemd5 as software output from `av1_amf`. Before, it failed on the first frame. - 8-bit AV1, `h264_amf`, `hevc_amf` (8 and 10 bit) and `vp9_amf` give unchanged framemd5 with software and AMF-surface output. Independent of #25525, #25146, #25147 and #25560, and merges cleanly with each of them. Written with Claude Opus 5.5 in Claude Code; `Assisted-by` trailer on the commit. >From 99a013c7d288a14dfd7d507bc2fb870ba712068e Mon Sep 17 00:00:00 2001 From: Julius Bairaktaris <[email protected]> Date: Wed, 28 Oct 2026 14:48:14 +0100 Subject: [PATCH] avcodec/amfdec: re-init the frames context when the surface format differs With AMF-surface output, amf_decode_init() creates the frames context from AMF_VIDEO_DECODER_OUTPUT_FORMAT, falling back to NV12 when the decoder has not detected a format yet. The context is only re-created on AMF_RESOLUTION_CHANGED, so it keeps NV12 when the decoder then outputs P010 at the same size. The AV1 decoder does not report its format before decoding, so every 10-bit AV1 stream is output as P010 surfaces in an NV12 frames context, and hwdownload to p010le fails with EINVAL. Re-create the frames context, keeping its size, when an output surface's format differs from its sw_format. Tested on Windows 11, RX 9070 XT, driver 32.0.32015.7029: 10-bit AV1 (raw OBU and Matroska) with -hwaccel amf -hwaccel_output_format amf and hwdownload to p010le now decodes, with the same framemd5 as software output from av1_amf; 8-bit AV1, h264_amf, hevc_amf (8 and 10 bit) and vp9_amf are unchanged. Assisted-by: Claude Opus 5.5 Signed-off-by: Julius Bairaktaris <[email protected]> --- libavcodec/amfdec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libavcodec/amfdec.c b/libavcodec/amfdec.c index 00a17360f55..017327f6bcb 100644 --- a/libavcodec/amfdec.c +++ b/libavcodec/amfdec.c @@ -512,6 +512,19 @@ static int amf_amfsurface_to_avframe(AVCodecContext *avctx, AMFSurface* surface, int format_amf; if (avctx->hw_device_ctx && ((AVHWDeviceContext*)avctx->hw_device_ctx->data)->type == AV_HWDEVICE_TYPE_AMF) { + AVHWFramesContext *frames_ctx; + enum AVPixelFormat sw_format; + + if (!avctx->hw_frames_ctx) + return AVERROR(EINVAL); + frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data; + sw_format = av_amf_to_av_format(surface->pVtbl->GetFormat(surface)); + if (sw_format != frames_ctx->sw_format) { + ret = amf_reinit_frames_context(avctx, sw_format, frames_ctx->width, frames_ctx->height); + if (ret < 0) + return ret; + } + // prepare frame similar to ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF); ret = ff_decode_frame_props(avctx, frame); -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
