From: Anton Baskanov Subject: [PATCH 2/4] quartz/vmr9: Copy the chroma planes separately for NV12 and YV12. Message-Id: <20210829133141.358214-2-baskanov@gmail.com> Date: Sun, 29 Aug 2021 20:31:39 +0700 In-Reply-To: <20210829133141.358214-1-baskanov@gmail.com> References: <20210829133141.358214-1-baskanov@gmail.com> DirectShow has stricter chroma plane alignment requirements than D3D. Fixes crash when playing back some videos with non-multiple-of-8 width. Signed-off-by: Anton Baskanov --- dlls/quartz/vmr9.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index 546af3d2a39..ed1cc6b729c 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -302,7 +302,25 @@ static HRESULT vmr_render(struct strmbase_renderer *iface, IMediaSample *sample) return hr; } - if (height > 0 && bitmap_header->biCompression == BI_RGB) + if (bitmap_header->biCompression == mmioFOURCC('N','V','1','2')) + { + BYTE *chroma_src = data + src_pitch * ((height + 1) & ~1); + BYTE *chroma_dst = (BYTE *)locked_rect.pBits + locked_rect.Pitch * height; + copy_plane(height, width, src_pitch, locked_rect.Pitch, data, locked_rect.pBits); + copy_plane(height / 2, width, src_pitch, locked_rect.Pitch, chroma_src, chroma_dst); + } + else if (bitmap_header->biCompression == mmioFOURCC('Y','V','1','2')) + { + int chroma_src_pitch = ((width + 1) / 2 + 3) & ~3; + BYTE *v_src = data + src_pitch * ((height + 1) & ~1); + BYTE *v_dst = (BYTE *)locked_rect.pBits + locked_rect.Pitch * height; + BYTE *u_src = v_src + chroma_src_pitch * ((height + 1) / 2); + BYTE *u_dst = v_dst + locked_rect.Pitch / 2 * (height / 2); + copy_plane(height, width, src_pitch, locked_rect.Pitch, data, locked_rect.pBits); + copy_plane(height / 2, width / 2, chroma_src_pitch, locked_rect.Pitch / 2, v_src, v_dst); + copy_plane(height / 2, width / 2, chroma_src_pitch, locked_rect.Pitch / 2, u_src, u_dst); + } + else if (height > 0 && bitmap_header->biCompression == BI_RGB) { copy_plane(height, width * depth / 8, -(int)src_pitch, locked_rect.Pitch, data + src_pitch * (height - 1), locked_rect.pBits); -- 2.25.1