1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2025-08-10 06:10:52 +02:00

lavu/hwcontext_vaapi: fix a race mapping to allow CSC to YUV420P

There's a race condition for YUV420P when mapping from pix_fmt
to VA fourcc, both I420 and YV12 could be found by pix_fmt.

Currently, vaapi_get_image_format() iterates over the query results
of pix_fmt and returns the first matching result in the order
declared in the driver. This may result in an incorrect image_format.

Now use fourcc to find the image_format.

Fixes:
ffmpeg -hwaccel vaapi -hwaccel_output_format vaapi -i INPUT \
-vf scale_vaapi=format=yuv420p,hwmap,format=yuv420p \
-vframes 1 -f rawvideo -y yuv420p.yuv

Signed-off-by: nyanmisaka <nst799610810@gmail.com>
This commit is contained in:
nyanmisaka
2025-08-07 22:32:20 +08:00
committed by Lynne
parent d643a5ba08
commit eb9070aba4

View File

@@ -72,6 +72,7 @@ typedef struct VAAPIDevicePriv {
typedef struct VAAPISurfaceFormat {
enum AVPixelFormat pix_fmt;
VAImageFormat image_format;
unsigned int fourcc;
} VAAPISurfaceFormat;
typedef struct VAAPIDeviceContext {
@@ -218,15 +219,21 @@ static int vaapi_get_image_format(AVHWDeviceContext *hwdev,
VAImageFormat **image_format)
{
VAAPIDeviceContext *ctx = hwdev->hwctx;
const VAAPIFormatDescriptor *desc;
int i;
desc = vaapi_format_from_pix_fmt(pix_fmt);
if (!desc || !image_format)
goto fail;
for (i = 0; i < ctx->nb_formats; i++) {
if (ctx->formats[i].pix_fmt == pix_fmt) {
if (image_format)
*image_format = &ctx->formats[i].image_format;
if (ctx->formats[i].fourcc == desc->fourcc) {
*image_format = &ctx->formats[i].image_format;
return 0;
}
}
fail:
return AVERROR(ENOSYS);
}
@@ -435,6 +442,7 @@ static int vaapi_device_init(AVHWDeviceContext *hwdev)
av_log(hwdev, AV_LOG_DEBUG, "Format %#x -> %s.\n",
fourcc, av_get_pix_fmt_name(pix_fmt));
ctx->formats[ctx->nb_formats].pix_fmt = pix_fmt;
ctx->formats[ctx->nb_formats].fourcc = fourcc;
ctx->formats[ctx->nb_formats].image_format = image_list[i];
++ctx->nb_formats;
}