Module: wine Branch: master Commit: 408a3074c4297a0004b8aa485d4cb3e296d3fe04 URL: https://source.winehq.org/git/wine.git/?a=commit;h=408a3074c4297a0004b8aa485...
Author: Zebediah Figura zfigura@codeweavers.com Date: Fri Jun 12 16:28:27 2020 -0500
quartz/vmr9: Implement IVMRWindowlessControl9::SetAspectRatioMode().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35215 Signed-off-by: Zebediah Figura z.figura12@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/quartz/tests/vmr9.c | 37 ++++++++++++++++++++ dlls/quartz/vmr9.c | 87 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 96 insertions(+), 28 deletions(-)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 14b6539a6b..a227a647f6 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -3770,6 +3770,7 @@ static void test_windowless_size(void) LONG width, height, aspect_width, aspect_height; IVMRWindowlessControl9 *windowless_control; IFilterGraph2 *graph = create_graph(); + VMR9AspectRatioMode aspect_mode; struct testfilter source; IMemAllocator *allocator; RECT src, dst, expect; @@ -3813,6 +3814,11 @@ static void test_windowless_size(void) hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, &width, NULL, &aspect_width, &aspect_height); ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+ aspect_mode = 0xdeadbeef; + hr = IVMRWindowlessControl9_GetAspectRatioMode(windowless_control, &aspect_mode); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(aspect_mode == VMR9ARMode_None, "Got mode %u.\n", aspect_mode); + width = height = 0xdeadbeef; hr = IVMRWindowlessControl9_GetNativeVideoSize(windowless_control, &width, &height, NULL, NULL); ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -3867,6 +3873,37 @@ static void test_windowless_size(void) SetRect(&expect, 0, 0, 640, 480); ok(EqualRect(&src, &expect), "Got window rect %s.\n", wine_dbgstr_rect(&src));
+ hr = IVMRWindowlessControl9_SetAspectRatioMode(windowless_control, VMR9ARMode_LetterBox); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + aspect_mode = 0xdeadbeef; + hr = IVMRWindowlessControl9_GetAspectRatioMode(windowless_control, &aspect_mode); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(aspect_mode == VMR9ARMode_LetterBox, "Got mode %u.\n", aspect_mode); + + memset(&src, 0xcc, sizeof(src)); + memset(&dst, 0xcc, sizeof(dst)); + hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst); + ok(hr == S_OK, "Got hr %#x.\n", hr); + SetRect(&expect, 4, 6, 16, 12); + ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src)); + SetRect(&expect, 40, 60, 120, 160); + ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst)); + + SetRect(&src, 0, 0, 32, 16); + SetRect(&dst, 0, 0, 640, 480); + hr = IVMRWindowlessControl9_SetVideoPosition(windowless_control, &src, &dst); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + memset(&src, 0xcc, sizeof(src)); + memset(&dst, 0xcc, sizeof(dst)); + hr = IVMRWindowlessControl9_GetVideoPosition(windowless_control, &src, &dst); + ok(hr == S_OK, "Got hr %#x.\n", hr); + SetRect(&expect, 0, 0, 32, 16); + ok(EqualRect(&src, &expect), "Got source rect %s.\n", wine_dbgstr_rect(&src)); + SetRect(&expect, 0, 0, 640, 480); + ok(EqualRect(&dst, &expect), "Got dest rect %s.\n", wine_dbgstr_rect(&dst)); + out: ref = IFilterGraph2_Release(graph); ok(!ref, "Got outstanding refcount %d.\n", ref); diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c index 776d927f2a..449943f2dc 100644 --- a/dlls/quartz/vmr9.c +++ b/dlls/quartz/vmr9.c @@ -106,6 +106,7 @@ struct quartz_vmr
LONG VideoWidth; LONG VideoHeight; + VMR9AspectRatioMode aspect_mode;
HANDLE run_event; }; @@ -1715,18 +1716,26 @@ static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessContr
static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode) { - struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); + struct quartz_vmr *filter = impl_from_IVMRWindowlessControl9(iface);
- FIXME("(%p/%p)->(...) stub\n", iface, This); - return E_NOTIMPL; + TRACE("filter %p, mode %p.\n", filter, mode); + + EnterCriticalSection(&filter->renderer.filter.csFilter); + *mode = filter->aspect_mode; + LeaveCriticalSection(&filter->renderer.filter.csFilter); + return S_OK; }
static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode) { - struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface); + struct quartz_vmr *filter = impl_from_IVMRWindowlessControl9(iface);
- FIXME("(%p/%p)->(...) stub\n", iface, This); - return E_NOTIMPL; + TRACE("filter %p, mode %u.\n", filter, mode); + + EnterCriticalSection(&filter->renderer.filter.csFilter); + filter->aspect_mode = mode; + LeaveCriticalSection(&filter->renderer.filter.csFilter); + return S_OK; }
static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND window) @@ -2625,37 +2634,59 @@ static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(struct default_presen static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR cookie, VMR9PresentationInfo *info) { - struct default_presenter *This = impl_from_IVMRImagePresenter9(iface); + struct default_presenter *presenter = impl_from_IVMRImagePresenter9(iface); + const struct quartz_vmr *filter = presenter->pVMR9; + IDirect3DDevice9 *device = presenter->d3d9_dev; + const RECT src = filter->window.src; + RECT dst = filter->window.dst; HRESULT hr; - BOOL render = FALSE;
- TRACE("presenter %p, cookie %#Ix, info %p.\n", This, cookie, info); + TRACE("presenter %p, cookie %#Ix, info %p.\n", presenter, cookie, info);
/* This might happen if we don't have active focus (eg on a different virtual desktop) */ - if (!This->d3d9_dev) + if (!device) return S_OK;
- /* Display image here */ - hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0); - if (FAILED(hr)) - FIXME("hr: %08x\n", hr); - hr = IDirect3DDevice9_BeginScene(This->d3d9_dev); - if (SUCCEEDED(hr)) - { - hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf); - render = SUCCEEDED(hr); - } - else - FIXME("BeginScene: %08x\n", hr); - hr = IDirect3DDevice9_EndScene(This->d3d9_dev); - if (render && SUCCEEDED(hr)) + if (FAILED(hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, + D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0))) + ERR("Failed to clear, hr %#x.\n", hr); + + if (FAILED(hr = IDirect3DDevice9_BeginScene(device))) + ERR("Failed to begin scene, hr %#x.\n", hr); + + VMR9_ImagePresenter_PresentOffscreenSurface(presenter, info->lpSurf); + + if (FAILED(hr = IDirect3DDevice9_EndScene(device))) + ERR("Failed to end scene, hr %#x.\n", hr); + + if (filter->aspect_mode == VMR9ARMode_LetterBox) { - hr = IDirect3DDevice9_Present(This->d3d9_dev, &This->pVMR9->window.src, - &This->pVMR9->window.dst, NULL, NULL); - if (FAILED(hr)) - FIXME("Presenting image: %08x\n", hr); + unsigned int src_width = src.right - src.left, src_height = src.bottom - src.top; + unsigned int dst_width = dst.right - dst.left, dst_height = dst.bottom - dst.top; + + if (src_width * dst_height > dst_width * src_height) + { + /* src is "wider" than dst. */ + unsigned int dst_center = (dst.top + dst.bottom) / 2; + unsigned int scaled_height = src_height * dst_width / src_width; + + dst.top = dst_center - scaled_height / 2; + dst.bottom = dst.top + scaled_height; + } + else if (src_width * dst_height < dst_width * src_height) + { + /* src is "taller" than dst. */ + unsigned int dst_center = (dst.left + dst.right) / 2; + unsigned int scaled_width = src_width * dst_height / src_height; + + dst.left = dst_center - scaled_width / 2; + dst.right = dst.left + scaled_width; + } }
+ if (FAILED(hr = IDirect3DDevice9_Present(device, &src, &dst, NULL, NULL))) + ERR("Failed to present, hr %#x.\n", hr); + return S_OK; }