[PATCH 2/4] quartz/vmr9: Copy the chroma planes separately for NV12 and YV12.

Anton Baskanov baskanov at gmail.com
Sun Aug 29 08:31:39 CDT 2021


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 <baskanov at gmail.com>
---
 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




More information about the wine-devel mailing list