diff --git a/src/image.c b/src/image.c index cd8d9d2..eb901f0 100644 --- a/src/image.c +++ b/src/image.c @@ -198,7 +198,11 @@ VAStatus RequestDeriveImage(VADriverContextP context, VASurfaceID surface_id, return status; } + /* Fully populate VAImageFormat to match QueryImageFormats output. */ + memset(&format, 0, sizeof(format)); format.fourcc = VA_FOURCC_NV12; + format.byte_order = VA_LSB_FIRST; + format.bits_per_pixel = 12; status = RequestCreateImage(context, &format, surface_object->width, surface_object->height, image); @@ -221,7 +225,25 @@ VAStatus RequestQueryImageFormats(VADriverContextP context, VAImageFormat *formats, int *formats_count) { request_log("ENTER RequestQueryImageFormats\n"); + + /* + * Populate the VAImageFormat fully per VAAPI spec for NV12 — + * not just .fourcc. Consumers (FFmpeg's hwcontext_vaapi, mpv, + * Firefox) read .byte_order and .bits_per_pixel; leaving them + * uninitialized inherits whatever caller-stack garbage is in + * the buffer and produces non-deterministic behavior. Reference: + * Mesa's gallium/frontends/va/image.c::vlVaQueryImageFormats and + * intel-vaapi-driver's i965_drv_video.c — both publish NV12 + * with byte_order=VA_LSB_FIRST and bits_per_pixel=12. + * + * For YUV formats, depth/red_mask/green_mask/blue_mask/alpha_mask + * are not meaningful (those describe RGB bit layouts); leave them + * zeroed via memset before populating. + */ + memset(&formats[0], 0, sizeof(formats[0])); formats[0].fourcc = VA_FOURCC_NV12; + formats[0].byte_order = VA_LSB_FIRST; + formats[0].bits_per_pixel = 12; *formats_count = 1; return VA_STATUS_SUCCESS;