From: Alfred Agrell floating@muncher.se
- Checks that it presents using the new device, instead of counting TerminateDevice - Works on Windows now
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=55649 --- dlls/quartz/tests/vmr9.c | 93 +++++++++++++++++++++++++++++++++++----- 1 file changed, 82 insertions(+), 11 deletions(-)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 447273a91df..4328b1beac4 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -866,6 +866,7 @@ struct testfilter { struct strmbase_filter filter; struct strmbase_source source; + AM_MEDIA_TYPE *mt; };
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface) @@ -900,8 +901,21 @@ static HRESULT WINAPI testsource_DecideAllocator(struct strmbase_source *iface, return S_OK; }
+static HRESULT testsource_get_media_type(struct strmbase_pin *pin, unsigned int index, AM_MEDIA_TYPE *mt) +{ + struct testfilter *filter = impl_from_strmbase_filter(pin->filter); + + if (!index && filter->mt) + { + CopyMediaType(mt, filter->mt); + return S_OK; + } + return VFW_S_NO_MORE_ITEMS; +} + static const struct strmbase_source_ops testsource_ops = { + .base.pin_get_media_type = testsource_get_media_type, .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection, .pfnDecideAllocator = testsource_DecideAllocator, }; @@ -911,6 +925,7 @@ static void testfilter_init(struct testfilter *filter) static const GUID clsid = {0xabacab}; strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops); strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops); + filter->mt = NULL; }
static void test_allocator(IMemInputPin *input) @@ -1586,7 +1601,7 @@ static void test_window_close(IPin *pin, IMemInputPin *input, IMediaControl *con ok(ret == 1, "Expected EC_USERABORT.\n");
ok(IsWindow(hwnd), "Window should exist.\n"); - ok(!IsWindowVisible(hwnd), "Window should be visible.\n"); + ok(!IsWindowVisible(hwnd), "Window should be invisible.\n");
thread = send_frame(input); ret = WaitForSingleObject(thread, 1000); @@ -2934,6 +2949,7 @@ struct presenter
D3DFORMAT format; DWORD accept_flags; + IDirect3DDevice9 *device; IDirect3DSurface9 *surfaces[5]; IVMRSurfaceAllocatorNotify9 *notify; unsigned int got_PresentImage, got_TerminateDevice; @@ -2979,9 +2995,13 @@ static HRESULT WINAPI presenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD static HRESULT WINAPI presenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR cookie, VMR9PresentationInfo *info) { struct presenter *presenter = impl_from_IVMRImagePresenter9(iface); + IDirect3DDevice9 *device; static const RECT rect;
if (winetest_debug > 1) trace("PresentImage()\n"); + IDirect3DSurface9_GetDevice(info->lpSurf, &device); + ok(device == presenter->device, "got %p, expected %p\n", device, presenter->device); + IDirect3DDevice9_Release(device); ok(cookie == 0xabacab, "Got cookie %#Ix.\n", cookie); todo_wine ok(info->dwFlags == VMR9Sample_TimeValid, "Got flags %#lx.\n", info->dwFlags); ok(!info->rtStart, "Got start time %s.\n", wine_dbgstr_longlong(info->rtStart)); @@ -3224,6 +3244,7 @@ static void test_renderless_formats(void) IBaseFilter_QueryInterface(filter, &IID_IVMRSurfaceAllocatorNotify9, (void **)¬ify);
hr = IVMRSurfaceAllocatorNotify9_SetD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY)); + presenter.device = device; if (hr == E_NOINTERFACE) { win_skip("Direct3D does not support video rendering.\n"); @@ -4307,12 +4328,11 @@ static void test_changed3ddevice(void) { VIDEOINFOHEADER vih = { + .rcSource = {4, 6, 16, 12}, + .rcTarget = {40, 60, 160, 120}, .bmiHeader.biSize = sizeof(BITMAPINFOHEADER), - .bmiHeader.biBitCount = 32, .bmiHeader.biWidth = 32, .bmiHeader.biHeight = 16, - .bmiHeader.biPlanes = 1, - .bmiHeader.biCompression = BI_RGB, }; AM_MEDIA_TYPE req_mt = { @@ -4329,18 +4349,24 @@ static void test_changed3ddevice(void) .refcount = 1, .accept_flags = VMR9AllocFlag_TextureSurface, }; + ALLOCATOR_PROPERTIES req_props = {5, 32 * 16 * 4, 1, 0}, ret_props; IBaseFilter *filter = create_vmr9(VMR9Mode_Renderless); + IDirect3DDevice9 *device, *device2 = NULL; IFilterGraph2 *graph = create_graph(); IVMRSurfaceAllocatorNotify9 *notify; - IDirect3DDevice9 *device, *device2; RECT rect = {0, 0, 640, 480}; struct testfilter source; + IMemAllocator *allocator; + IMediaControl *control; + IMemInputPin *input; + OAFilterState state; IPin *pin = NULL; HWND window; HRESULT hr; ULONG ref;
testfilter_init(&source); + source.mt = &req_mt;
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); window = CreateWindowA("static", "quartz_test", WS_OVERLAPPEDWINDOW, 0, 0, @@ -4360,6 +4386,7 @@ static void test_changed3ddevice(void) ok(hr == S_OK, "Got hr %#lx.\n", hr);
hr = IVMRSurfaceAllocatorNotify9_SetD3DDevice(notify, device, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY)); + presenter.device = device; if (hr == E_NOINTERFACE) { win_skip("Direct3D does not support video rendering.\n"); @@ -4374,20 +4401,59 @@ static void test_changed3ddevice(void) hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt); ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ IPin_QueryInterface(pin, &IID_IMemInputPin, (void **)&input); + + hr = IMemInputPin_GetAllocator(input, &allocator); + todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr); + if (hr == VFW_E_NO_ALLOCATOR) + { + CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, + &IID_IMemAllocator, (void **)&allocator); + + hr = IMemInputPin_NotifyAllocator(input, allocator, TRUE); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + } + hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMemAllocator_Commit(allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + device2 = create_device(window); ok(device2 != NULL, "Couldn't create device\n");
- ok(presenter.got_TerminateDevice == 0, "got %d\n", presenter.got_TerminateDevice); - hr = IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(notify, device2, MonitorFromWindow(window, MONITOR_DEFAULTTOPRIMARY)); ok(hr == S_OK, "Got hr %#lx.\n", hr); - ok(presenter.got_TerminateDevice == 1, "got %d\n", presenter.got_TerminateDevice); + presenter.device = device2; + presenter.got_PresentImage = 0; + Sleep(200); /* ChangeD3DDevice is partially asynchronous */
- IDirect3DDevice9_Release(device2); + hr = IMemAllocator_Decommit(allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMemAllocator_SetProperties(allocator, &req_props, &ret_props); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + hr = IMemAllocator_Commit(allocator); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control); + hr = IMediaControl_Run(control); + ok(hr == S_FALSE, "Got hr %#lx.\n", hr); + + join_thread(send_frame(input)); + + hr = IMediaControl_GetState(control, 100, &state); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + ok(presenter.got_PresentImage >= 1, "Got %u calls to PresentImage().\n", presenter.got_PresentImage); + IMediaControl_Release(control); + + hr = IMediaControl_Stop(control); + ok(hr == S_OK, "Got hr %#lx.\n", hr); + + IMemAllocator_Release(allocator); + IMemInputPin_Release(input); + IPin_Release(pin);
out: - if (pin) - IPin_Release(pin); ref = IFilterGraph2_Release(graph); ok(!ref, "Got outstanding refcount %ld.\n", ref); IVMRSurfaceAllocatorNotify9_Release(notify); @@ -4395,6 +4461,11 @@ out: ok(!ref, "Got outstanding refcount %ld.\n", ref); ref = IDirect3DDevice9_Release(device); ok(!ref, "Got outstanding refcount %ld.\n", ref); + if (device2) + { + ref = IDirect3DDevice9_Release(device2); + ok(!ref, "Got outstanding refcount %ld.\n", ref); + } DestroyWindow(window); }