[PATCH 2/3] quartz/vmr9: Implement IVMRWindowlessControl9::SetAspectRatioMode().
Zebediah Figura
z.figura12 at gmail.com
Fri Jun 12 16:28:27 CDT 2020
From: Zebediah Figura <zfigura at codeweavers.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=35215
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
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 14b6539a6bd..a227a647f65 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 776d927f2ab..449943f2dc3 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;
}
--
2.27.0
More information about the wine-devel
mailing list