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@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);