Commit c9c3545034 for ffmpeg
commit c9c35450343397c0ed6df2579d532f179dd8a2f3
Author: Lynne <dev@lynne.ee>
Date: Sat Oct 3 18:01:25 2026 +0900
hwcontext_vulkan: use one image per plane for unaligned subsampled frames
Formats with a _420 or _422 suffix require even dimensions, but frames
contexts of subsampled formats with odd dimensions still got a single
multiplane image, whose chroma planes the drivers rounded down: 320x240
instead of 321x241 at 641x481. FFV1 decoding through the Vulkan hwaccel
corrupted the chroma of such frames, and ffv1_vulkan encoding was not
lossless, on both RADV and ANV.
Use one image per plane for them instead. Hardware decoders are not
affected, as they set the image format and align the frames context
dimensions themselves. Decoding broke when 713e3c4f91 stopped aligning
the frames of decoders without a video profile.
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index a502b9de1d..fab3532df9 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -3229,6 +3229,7 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
VkImageUsageFlags supported_usage;
FFVulkanFunctions *vk = &p->vkctx.vkfn;
const struct FFVkFormatEntry *fmt;
+ const AVPixFmtDescriptor *desc;
int disable_multiplane = p->disable_multiplane ||
(hwctx->flags & AV_VK_FRAME_FLAG_DISABLE_MULTIPLANE);
int is_lone_dpb = ((hwctx->usage & VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR) ||
@@ -3252,6 +3253,12 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc)
return AVERROR(ENOTSUP);
}
+ /* _420 and _422 formats need even dimensions, use one image per plane */
+ desc = av_pix_fmt_desc_get(hwfc->sw_format);
+ if ((hwfc->width & ((1 << desc->log2_chroma_w) - 1)) ||
+ (hwfc->height & ((1 << desc->log2_chroma_h) - 1)))
+ disable_multiplane = 1;
+
if (hwctx->format[0] != VK_FORMAT_UNDEFINED) {
if (hwctx->format[0] != fmt->vkf) {
for (int i = 0; i < fmt->nb_images_fallback; i++) {