[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