evr/tests: Skip tests if D3D9 is unusable.
[wine.git] / dlls / evr / tests / evr.c
blob25fb1978443844c3021ceee39c6a3662e0fcf8b7
1 /*
2 * Enhanced Video Renderer filter unit tests
4 * Copyright 2018 Zebediah Figura
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define COBJMACROS
23 #include "dshow.h"
24 #include "wine/test.h"
25 #include "d3d9.h"
26 #include "evr.h"
27 #include "mferror.h"
28 #include "mfapi.h"
29 #include "initguid.h"
30 #include "evr9.h"
32 static const WCHAR sink_id[] = L"EVR Input0";
34 static void load_resource(const WCHAR *filename, const BYTE **data, DWORD *length)
36 HRSRC resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA);
37 ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError());
38 *data = LockResource(LoadResource(GetModuleHandleW(NULL), resource));
39 *length = SizeofResource(GetModuleHandleW(NULL), resource);
42 static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect)
44 DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
46 /* skip BMP header from the dump */
47 size = *(DWORD *)(expect + 2 + 2 * sizeof(DWORD));
48 *length = *length + size;
49 expect = expect + size;
51 for (y = 0; y < height; y++, data += width * 4, expect += width * 4)
53 if (y < rect->top || y >= rect->bottom) continue;
54 for (x = 0; x < width; x++)
56 if (x < rect->left || x >= rect->right) continue;
57 diff += abs((int)expect[4 * x + 0] - (int)data[4 * x + 0]);
58 diff += abs((int)expect[4 * x + 1] - (int)data[4 * x + 1]);
59 diff += abs((int)expect[4 * x + 2] - (int)data[4 * x + 2]);
63 size = (rect->right - rect->left) * (rect->bottom - rect->top) * 3;
64 return diff * 100 / 256 / size;
67 static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output)
69 DWORD width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
70 static const char magic[2] = "BM";
71 struct
73 DWORD length;
74 DWORD reserved;
75 DWORD offset;
76 BITMAPINFOHEADER biHeader;
77 } header =
79 .length = length + sizeof(header) + 2, .offset = sizeof(header) + 2,
80 .biHeader =
82 .biSize = sizeof(BITMAPINFOHEADER), .biWidth = width, .biHeight = height, .biPlanes = 1,
83 .biBitCount = 32, .biCompression = BI_RGB, .biSizeImage = width * height * 4,
86 DWORD written;
87 BOOL ret;
89 ret = WriteFile(output, magic, sizeof(magic), &written, NULL);
90 ok(ret, "WriteFile failed, error %lu\n", GetLastError());
91 ok(written == sizeof(magic), "written %lu bytes\n", written);
92 ret = WriteFile(output, &header, sizeof(header), &written, NULL);
93 ok(ret, "WriteFile failed, error %lu\n", GetLastError());
94 ok(written == sizeof(header), "written %lu bytes\n", written);
95 ret = WriteFile(output, data, length, &written, NULL);
96 ok(ret, "WriteFile failed, error %lu\n", GetLastError());
97 ok(written == length, "written %lu bytes\n", written);
100 #define check_rgb32_data(a, b, c, d) check_rgb32_data_(__LINE__, a, b, c, d)
101 static DWORD check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, DWORD length, const RECT *rect)
103 WCHAR output_path[MAX_PATH];
104 const BYTE *expect_data;
105 HRSRC resource;
106 HANDLE output;
108 GetTempPathW(ARRAY_SIZE(output_path), output_path);
109 lstrcatW(output_path, filename);
110 output = CreateFileW(output_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
111 ok(output != INVALID_HANDLE_VALUE, "CreateFileW failed, error %lu\n", GetLastError());
112 dump_rgb32(data, length, rect, output);
113 trace("created %s\n", debugstr_w(output_path));
114 CloseHandle(output);
116 resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA);
117 ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError());
118 expect_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource));
120 return compare_rgb32(data, &length, rect, expect_data);
123 static void set_rect(MFVideoNormalizedRect *rect, float left, float top, float right, float bottom)
125 rect->left = left;
126 rect->top = top;
127 rect->right = right;
128 rect->bottom = bottom;
131 static HWND create_window(void)
133 RECT r = {0, 0, 640, 480};
135 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
137 return CreateWindowA("static", "evr_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
138 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
141 static IDirect3DDevice9 *create_device(HWND focus_window)
143 D3DPRESENT_PARAMETERS present_parameters = {0};
144 IDirect3DDevice9 *device = NULL;
145 IDirect3D9 *d3d9;
147 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
148 ok(!!d3d9, "Failed to create a D3D object.\n");
150 present_parameters.BackBufferWidth = 640;
151 present_parameters.BackBufferHeight = 480;
152 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
153 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
154 present_parameters.hDeviceWindow = focus_window;
155 present_parameters.Windowed = TRUE;
156 present_parameters.EnableAutoDepthStencil = TRUE;
157 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
159 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
160 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
162 IDirect3D9_Release(d3d9);
164 return device;
167 static IBaseFilter *create_evr(void)
169 IBaseFilter *filter = NULL;
170 HRESULT hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC_SERVER,
171 &IID_IBaseFilter, (void **)&filter);
172 ok(hr == S_OK, "Got hr %#lx.\n", hr);
173 return filter;
176 static IFilterGraph2 *create_graph(void)
178 IFilterGraph2 *ret;
179 HRESULT hr;
181 hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IFilterGraph2, (void **)&ret);
182 ok(hr == S_OK, "Failed to create FilterGraph: %#lx\n", hr);
183 return ret;
186 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
187 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
189 ULONG rc;
190 IUnknown_AddRef(obj);
191 rc = IUnknown_Release(obj);
192 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %ld, expected %ld.\n", rc, ref);
195 static ULONG get_refcount(void *iface)
197 IUnknown *unknown = iface;
198 IUnknown_AddRef(unknown);
199 return IUnknown_Release(unknown);
202 static const GUID test_iid = {0x33333333};
203 static LONG outer_ref = 1;
205 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
207 if (IsEqualGUID(iid, &IID_IUnknown)
208 || IsEqualGUID(iid, &IID_IBaseFilter)
209 || IsEqualGUID(iid, &test_iid))
211 *out = (IUnknown *)0xdeadbeef;
212 return S_OK;
214 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
215 return E_NOINTERFACE;
218 static ULONG WINAPI outer_AddRef(IUnknown *iface)
220 return InterlockedIncrement(&outer_ref);
223 static ULONG WINAPI outer_Release(IUnknown *iface)
225 return InterlockedDecrement(&outer_ref);
228 static const IUnknownVtbl outer_vtbl =
230 outer_QueryInterface,
231 outer_AddRef,
232 outer_Release,
235 static IUnknown test_outer = {&outer_vtbl};
237 static void test_aggregation(void)
239 IBaseFilter *filter, *filter2;
240 IMFVideoPresenter *presenter;
241 IUnknown *unk, *unk2;
242 IMFTransform *mixer;
243 HRESULT hr;
244 ULONG ref;
246 filter = (IBaseFilter *)0xdeadbeef;
247 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
248 &IID_IBaseFilter, (void **)&filter);
249 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
250 ok(!filter, "Got interface %p.\n", filter);
252 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
253 &IID_IUnknown, (void **)&unk);
254 ok(hr == S_OK, "Got hr %#lx.\n", hr);
255 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
256 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
257 ref = get_refcount(unk);
258 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
260 ref = IUnknown_AddRef(unk);
261 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
262 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
264 ref = IUnknown_Release(unk);
265 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
266 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
268 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
269 ok(hr == S_OK, "Got hr %#lx.\n", hr);
270 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
271 IUnknown_Release(unk2);
273 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
274 ok(hr == S_OK, "Got hr %#lx.\n", hr);
276 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
277 ok(hr == S_OK, "Got hr %#lx.\n", hr);
278 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
280 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
281 ok(hr == S_OK, "Got hr %#lx.\n", hr);
282 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
284 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
285 ok(hr == E_NOINTERFACE, "Got hr %#lx.\n", hr);
286 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
288 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
289 ok(hr == S_OK, "Got hr %#lx.\n", hr);
290 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
292 IBaseFilter_Release(filter);
293 ref = IUnknown_Release(unk);
294 ok(!ref, "Got unexpected refcount %ld.\n", ref);
295 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
297 /* Default presenter. */
298 presenter = (void *)0xdeadbeef;
299 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter,
300 (void **)&presenter);
301 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
302 ok(!presenter, "Got interface %p.\n", presenter);
304 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
305 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Unexpected hr %#lx.\n", hr);
306 if (SUCCEEDED(hr))
308 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
309 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
310 ref = get_refcount(unk);
311 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
313 IUnknown_Release(unk);
316 /* Default mixer. */
317 presenter = (void *)0xdeadbeef;
318 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
319 (void **)&mixer);
320 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
321 ok(!mixer, "Got interface %p.\n", mixer);
323 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
324 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
325 ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
326 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
327 ref = get_refcount(unk);
328 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
330 IUnknown_Release(unk);
333 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
334 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
336 IUnknown *iface = iface_ptr;
337 HRESULT hr, expected_hr;
338 IUnknown *unk;
340 expected_hr = supported ? S_OK : E_NOINTERFACE;
342 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
343 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
344 if (SUCCEEDED(hr))
345 IUnknown_Release(unk);
348 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
349 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
351 IUnknown *iface = iface_ptr;
352 HRESULT hr, expected_hr;
353 IUnknown *unk;
355 expected_hr = supported ? S_OK : E_NOINTERFACE;
357 hr = MFGetService(iface, service, iid, (void **)&unk);
358 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
359 if (SUCCEEDED(hr))
360 IUnknown_Release(unk);
363 static void test_interfaces(void)
365 IBaseFilter *filter = create_evr(), *filter2;
366 IUnknown *unk;
367 HRESULT hr;
368 ULONG ref;
370 check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
371 check_interface(filter, &IID_IBaseFilter, TRUE);
372 check_interface(filter, &IID_IEVRFilterConfig, TRUE);
373 check_interface(filter, &IID_IMFGetService, TRUE);
374 check_interface(filter, &IID_IMFVideoRenderer, TRUE);
375 check_interface(filter, &IID_IMediaFilter, TRUE);
376 check_interface(filter, &IID_IMediaPosition, TRUE);
377 check_interface(filter, &IID_IMediaSeeking, TRUE);
378 check_interface(filter, &IID_IMediaEventSink, TRUE);
379 check_interface(filter, &IID_IPersist, TRUE);
380 check_interface(filter, &IID_IUnknown, TRUE);
382 check_interface(filter, &IID_IBasicAudio, FALSE);
383 check_interface(filter, &IID_IBasicVideo, FALSE);
384 check_interface(filter, &IID_IDirectXVideoMemoryConfiguration, FALSE);
385 check_interface(filter, &IID_IMemInputPin, FALSE);
386 check_interface(filter, &IID_IPersistPropertyBag, FALSE);
387 check_interface(filter, &IID_IPin, FALSE);
388 check_interface(filter, &IID_IReferenceClock, FALSE);
389 check_interface(filter, &IID_IVideoWindow, FALSE);
391 /* The scope of IMediaEventSink */
392 hr = IBaseFilter_QueryInterface(filter, &IID_IMediaEventSink, (void **)&unk);
393 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
394 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter2);
395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
396 ok(filter == filter2, "Unexpected pointer.\n");
397 IBaseFilter_Release(filter2);
398 IUnknown_Release(unk);
400 ref = IBaseFilter_Release(filter);
401 ok(!ref, "Got unexpected refcount %ld.\n", ref);
404 static void test_enum_pins(void)
406 IBaseFilter *filter = create_evr();
407 IEnumPins *enum1, *enum2;
408 ULONG count, ref;
409 IPin *pins[2];
410 HRESULT hr;
412 ref = get_refcount(filter);
413 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
415 hr = IBaseFilter_EnumPins(filter, NULL);
416 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
418 hr = IBaseFilter_EnumPins(filter, &enum1);
419 ok(hr == S_OK, "Got hr %#lx.\n", hr);
420 ref = get_refcount(filter);
421 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
422 ref = get_refcount(enum1);
423 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
425 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
426 ok(hr == E_POINTER, "Got hr %#lx.\n", hr);
428 hr = IEnumPins_Next(enum1, 1, pins, NULL);
429 ok(hr == S_OK, "Got hr %#lx.\n", hr);
430 ref = get_refcount(filter);
431 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
432 ref = get_refcount(pins[0]);
433 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
434 ref = get_refcount(enum1);
435 ok(ref == 1, "Got unexpected refcount %ld.\n", ref);
436 IPin_Release(pins[0]);
437 ref = get_refcount(filter);
438 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
440 hr = IEnumPins_Next(enum1, 1, pins, NULL);
441 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
443 hr = IEnumPins_Reset(enum1);
444 ok(hr == S_OK, "Got hr %#lx.\n", hr);
446 hr = IEnumPins_Next(enum1, 1, pins, &count);
447 ok(hr == S_OK, "Got hr %#lx.\n", hr);
448 ok(count == 1, "Got count %lu.\n", count);
449 IPin_Release(pins[0]);
451 hr = IEnumPins_Next(enum1, 1, pins, &count);
452 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
453 ok(!count, "Got count %lu.\n", count);
455 hr = IEnumPins_Reset(enum1);
456 ok(hr == S_OK, "Got hr %#lx.\n", hr);
458 hr = IEnumPins_Next(enum1, 2, pins, NULL);
459 ok(hr == E_INVALIDARG, "Got hr %#lx.\n", hr);
461 hr = IEnumPins_Next(enum1, 2, pins, &count);
462 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
463 ok(count == 1, "Got count %lu.\n", count);
464 IPin_Release(pins[0]);
466 hr = IEnumPins_Reset(enum1);
467 ok(hr == S_OK, "Got hr %#lx.\n", hr);
469 hr = IEnumPins_Clone(enum1, &enum2);
470 ok(hr == S_OK, "Got hr %#lx.\n", hr);
472 hr = IEnumPins_Skip(enum1, 2);
473 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
475 hr = IEnumPins_Skip(enum1, 1);
476 ok(hr == S_OK, "Got hr %#lx.\n", hr);
478 hr = IEnumPins_Skip(enum1, 1);
479 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
481 hr = IEnumPins_Next(enum1, 1, pins, NULL);
482 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
484 hr = IEnumPins_Next(enum2, 1, pins, NULL);
485 ok(hr == S_OK, "Got hr %#lx.\n", hr);
486 IPin_Release(pins[0]);
488 IEnumPins_Release(enum2);
489 IEnumPins_Release(enum1);
490 ref = IBaseFilter_Release(filter);
491 ok(!ref, "Got outstanding refcount %ld.\n", ref);
494 static void test_find_pin(void)
496 IBaseFilter *filter = create_evr();
497 IEnumPins *enum_pins;
498 IPin *pin, *pin2;
499 HRESULT hr;
500 ULONG ref;
502 hr = IBaseFilter_EnumPins(filter, &enum_pins);
503 ok(hr == S_OK, "Got hr %#lx.\n", hr);
505 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
506 ok(hr == S_OK, "Got hr %#lx.\n", hr);
507 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
508 ok(hr == S_OK, "Got hr %#lx.\n", hr);
509 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
510 IPin_Release(pin2);
511 IPin_Release(pin);
513 IEnumPins_Release(enum_pins);
514 ref = IBaseFilter_Release(filter);
515 ok(!ref, "Got outstanding refcount %ld.\n", ref);
518 static void test_pin_info(void)
520 IBaseFilter *filter = create_evr();
521 PIN_DIRECTION dir;
522 PIN_INFO info;
523 HRESULT hr;
524 WCHAR *id;
525 ULONG ref;
526 IPin *pin;
528 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
529 ok(hr == S_OK, "Got hr %#lx.\n", hr);
530 ref = get_refcount(filter);
531 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
532 ref = get_refcount(pin);
533 ok(ref == 2, "Got unexpected refcount %ld.\n", ref);
535 hr = IPin_QueryPinInfo(pin, &info);
536 ok(hr == S_OK, "Got hr %#lx.\n", hr);
537 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
538 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
539 ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
540 ref = get_refcount(filter);
541 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
542 ref = get_refcount(pin);
543 ok(ref == 3, "Got unexpected refcount %ld.\n", ref);
544 IBaseFilter_Release(info.pFilter);
546 hr = IPin_QueryDirection(pin, &dir);
547 ok(hr == S_OK, "Got hr %#lx.\n", hr);
548 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
550 hr = IPin_QueryId(pin, &id);
551 ok(hr == S_OK, "Got hr %#lx.\n", hr);
552 ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
553 CoTaskMemFree(id);
555 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
556 ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
558 IPin_Release(pin);
559 ref = IBaseFilter_Release(filter);
560 ok(!ref, "Got outstanding refcount %ld.\n", ref);
563 static unsigned int check_event_code(IMediaEvent *eventsrc, DWORD timeout, LONG expected_code, LONG_PTR expected1, LONG_PTR expected2)
565 LONG_PTR param1, param2;
566 unsigned int ret = 0;
567 HRESULT hr;
568 LONG code;
570 while ((hr = IMediaEvent_GetEvent(eventsrc, &code, &param1, &param2, timeout)) == S_OK)
572 if (code == expected_code)
574 ok(param1 == expected1, "Got param1 %#Ix.\n", param1);
575 ok(param2 == expected2, "Got param2 %#Ix.\n", param2);
576 ret++;
578 IMediaEvent_FreeEventParams(eventsrc, code, param1, param2);
579 timeout = 0;
581 ok(hr == E_ABORT, "Got hr %#lx.\n", hr);
583 return ret;
586 static unsigned int check_ec_complete(IMediaEvent *eventsrc, DWORD timeout)
588 return check_event_code(eventsrc, timeout, EC_COMPLETE, S_OK, 0);
591 static void test_unconnected_eos(void)
593 IBaseFilter *filter = create_evr();
594 IFilterGraph2 *graph = create_graph();
595 IMediaControl *control;
596 IMediaEvent *eventsrc;
597 unsigned int ret;
598 HRESULT hr;
599 ULONG ref;
601 hr = IFilterGraph2_AddFilter(graph, filter, L"renderer");
602 ok(hr == S_OK, "Got hr %#lx.\n", hr);
604 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaControl, (void **)&control);
605 ok(hr == S_OK, "Got hr %#lx.\n", hr);
607 hr = IFilterGraph2_QueryInterface(graph, &IID_IMediaEvent, (void **)&eventsrc);
608 ok(hr == S_OK, "Got hr %#lx.\n", hr);
610 ret = check_ec_complete(eventsrc, 0);
611 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
613 hr = IMediaControl_Pause(control);
614 ok(hr == S_OK, "Got hr %#lx.\n", hr);
616 ret = check_ec_complete(eventsrc, 0);
617 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
619 hr = IMediaControl_Run(control);
620 ok(hr == S_OK, "Got hr %#lx.\n", hr);
622 ret = check_ec_complete(eventsrc, 0);
623 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
625 hr = IMediaControl_Pause(control);
626 ok(hr == S_OK, "Got hr %#lx.\n", hr);
628 ret = check_ec_complete(eventsrc, 0);
629 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
631 hr = IMediaControl_Run(control);
632 ok(hr == S_OK, "Got hr %#lx.\n", hr);
634 ret = check_ec_complete(eventsrc, 0);
635 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
637 hr = IMediaControl_Stop(control);
638 ok(hr == S_OK, "Got hr %#lx.\n", hr);
640 ret = check_ec_complete(eventsrc, 0);
641 ok(!ret, "Got %u EC_COMPLETE events.\n", ret);
643 hr = IMediaControl_Run(control);
644 ok(hr == S_OK, "Got hr %#lx.\n", hr);
646 ret = check_ec_complete(eventsrc, 0);
647 ok(ret == 1, "Got %u EC_COMPLETE events.\n", ret);
649 IMediaControl_Release(control);
650 IMediaEvent_Release(eventsrc);
651 ref = IFilterGraph2_Release(graph);
652 ok(!ref, "Got outstanding refcount %ld.\n", ref);
653 ref = IBaseFilter_Release(filter);
654 ok(!ref, "Got outstanding refcount %ld.\n", ref);
657 static void test_misc_flags(void)
659 IBaseFilter *filter = create_evr();
660 IAMFilterMiscFlags *misc_flags;
661 ULONG ref, flags;
662 HRESULT hr;
664 hr = IBaseFilter_QueryInterface(filter, &IID_IAMFilterMiscFlags, (void **)&misc_flags);
665 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
667 flags = IAMFilterMiscFlags_GetMiscFlags(misc_flags);
668 ok(flags == AM_FILTER_MISC_FLAGS_IS_RENDERER, "Unexpected flags %#lx.\n", flags);
669 IAMFilterMiscFlags_Release(misc_flags);
671 ref = IBaseFilter_Release(filter);
672 ok(!ref, "Got outstanding refcount %ld.\n", ref);
675 static void test_display_control(void)
677 IBaseFilter *filter = create_evr();
678 IMFVideoDisplayControl *display_control;
679 HRESULT hr;
680 ULONG ref;
682 hr = MFGetService((IUnknown *)filter, &MR_VIDEO_RENDER_SERVICE,
683 &IID_IMFVideoDisplayControl, (void **)&display_control);
684 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
686 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, 0);
687 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
689 IMFVideoDisplayControl_Release(display_control);
691 ref = IBaseFilter_Release(filter);
692 ok(!ref, "Got outstanding refcount %ld.\n", ref);
695 static void test_service_lookup(void)
697 IBaseFilter *filter = create_evr();
698 IMFTopologyServiceLookup *service_lookup;
699 IUnknown *unk;
700 DWORD count;
701 HRESULT hr;
702 ULONG ref;
704 hr = IBaseFilter_QueryInterface(filter, &IID_IMFTopologyServiceLookup, (void **)&service_lookup);
705 if (FAILED(hr))
707 win_skip("IMFTopologyServiceLookup is not exposed.\n");
708 IBaseFilter_Release(filter);
709 return;
711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
713 hr = IMFTopologyServiceLookup_QueryInterface(service_lookup, &IID_IBaseFilter, (void **)&unk);
714 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
715 ok(unk == (IUnknown *)filter, "Unexpected pointer.\n");
716 IUnknown_Release(unk);
718 count = 1;
719 hr = IMFTopologyServiceLookup_LookupService(service_lookup, MF_SERVICE_LOOKUP_GLOBAL, 0,
720 &MR_VIDEO_RENDER_SERVICE, &IID_IMediaEventSink, (void **)&unk, &count);
721 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#lx.\n", hr);
723 IMFTopologyServiceLookup_Release(service_lookup);
725 ref = IBaseFilter_Release(filter);
726 ok(!ref, "Got outstanding refcount %ld.\n", ref);
729 static void test_query_accept(void)
731 IBaseFilter *filter = create_evr();
732 AM_MEDIA_TYPE req_mt = {{0}};
733 VIDEOINFOHEADER vih =
735 {0}, {0}, 0, 0, 0,
736 {sizeof(BITMAPINFOHEADER), 32, 24, 1, 0, 0xdeadbeef}
738 unsigned int i;
739 HRESULT hr;
740 ULONG ref;
741 IPin *pin;
743 static const GUID *subtype_tests[] =
745 &MEDIASUBTYPE_RGB32,
746 &MEDIASUBTYPE_YUY2,
749 static const GUID *unsupported_subtype_tests[] =
751 &MEDIASUBTYPE_RGB8,
754 IBaseFilter_FindPin(filter, L"EVR Input0", &pin);
756 req_mt.majortype = MEDIATYPE_Video;
757 req_mt.formattype = FORMAT_VideoInfo;
758 req_mt.cbFormat = sizeof(VIDEOINFOHEADER);
759 req_mt.pbFormat = (BYTE *)&vih;
761 for (i = 0; i < ARRAY_SIZE(subtype_tests); ++i)
763 memcpy(&req_mt.subtype, subtype_tests[i], sizeof(GUID));
764 hr = IPin_QueryAccept(pin, &req_mt);
765 ok(hr == S_OK, "Got hr %#lx.\n", hr);
768 for (i = 0; i < ARRAY_SIZE(unsupported_subtype_tests); ++i)
770 memcpy(&req_mt.subtype, unsupported_subtype_tests[i], sizeof(GUID));
771 hr = IPin_QueryAccept(pin, &req_mt);
772 ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
775 IPin_Release(pin);
777 ref = IBaseFilter_Release(filter);
778 ok(!ref, "Got outstanding refcount %ld.\n", ref);
781 static IMFMediaType * create_video_type(const GUID *subtype)
783 IMFMediaType *video_type;
784 HRESULT hr;
786 hr = MFCreateMediaType(&video_type);
787 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
789 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
790 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
792 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
793 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
795 return video_type;
798 static void test_default_mixer(void)
800 DWORD input_min, input_max, output_min, output_max;
801 IMFAttributes *attributes, *attributes2;
802 IMFVideoMixerControl2 *mixer_control2;
803 MFT_OUTPUT_STREAM_INFO output_info;
804 MFT_INPUT_STREAM_INFO input_info;
805 DWORD input_count, output_count;
806 IMFVideoProcessor *processor;
807 IMFVideoDeviceID *deviceid;
808 MFVideoNormalizedRect rect;
809 DWORD input_id, output_id;
810 IMFTransform *transform;
811 DXVA2_ValueRange range;
812 DXVA2_Fixed32 dxva_value;
813 UINT32 count, value;
814 COLORREF color;
815 unsigned int i;
816 DWORD ids[16];
817 IUnknown *unk;
818 DWORD flags;
819 GUID *guids;
820 HRESULT hr;
821 IID iid;
823 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
824 ok(hr == S_OK, "Failed to create default mixer, hr %#lx.\n", hr);
826 check_interface(transform, &IID_IMFQualityAdvise, TRUE);
827 check_interface(transform, &IID_IMFClockStateSink, TRUE);
828 check_interface(transform, &IID_IMFTopologyServiceLookupClient, TRUE);
829 check_interface(transform, &IID_IMFGetService, TRUE);
830 check_interface(transform, &IID_IMFAttributes, TRUE);
831 check_interface(transform, &IID_IMFVideoMixerBitmap, TRUE);
832 check_interface(transform, &IID_IMFVideoPositionMapper, TRUE);
833 check_interface(transform, &IID_IMFVideoProcessor, TRUE);
834 check_interface(transform, &IID_IMFVideoMixerControl, TRUE);
835 check_interface(transform, &IID_IMFVideoDeviceID, TRUE);
836 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerBitmap, TRUE);
837 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, TRUE);
838 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, TRUE);
839 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
840 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFTransform, FALSE);
842 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_RENDER_SERVICE, &IID_IUnknown, (void **)&unk);
843 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#lx.\n", hr);
845 if (SUCCEEDED(MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl2, (void **)&mixer_control2)))
847 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, NULL);
848 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
850 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, &flags);
851 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
852 ok(!flags, "Unexpected flags %#lx.\n", flags);
854 IMFVideoMixerControl2_Release(mixer_control2);
857 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, (void **)&processor);
858 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
860 hr = IMFVideoProcessor_GetBackgroundColor(processor, NULL);
861 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
863 color = 1;
864 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
865 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
866 ok(!color, "Unexpected color %#lx.\n", color);
868 hr = IMFVideoProcessor_SetBackgroundColor(processor, 0x00121212);
869 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
871 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
873 ok(color == 0x121212, "Unexpected color %#lx.\n", color);
875 hr = IMFVideoProcessor_GetFilteringRange(processor, DXVA2_DetailFilterChromaLevel, &range);
876 todo_wine
877 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
879 hr = IMFVideoProcessor_GetFilteringValue(processor, DXVA2_DetailFilterChromaLevel, &dxva_value);
880 todo_wine
881 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
883 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
884 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
886 IMFVideoProcessor_Release(processor);
888 hr = IMFTransform_SetOutputBounds(transform, 100, 10);
889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
891 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid);
892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
894 hr = IMFTransform_GetAttributes(transform, NULL);
895 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
897 hr = IMFTransform_GetAttributes(transform, &attributes);
898 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
900 hr = IMFTransform_GetAttributes(transform, &attributes2);
901 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
902 ok(attributes == attributes2, "Unexpected attributes instance.\n");
903 IMFAttributes_Release(attributes2);
905 hr = IMFTransform_QueryInterface(transform, &IID_IMFAttributes, (void **)&attributes2);
906 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
907 ok(attributes != attributes2, "Unexpected attributes instance.\n");
909 hr = IMFAttributes_QueryInterface(attributes2, &IID_IMFTransform, (void **)&unk);
910 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
911 IUnknown_Release(unk);
913 hr = IMFAttributes_GetCount(attributes2, &count);
914 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
915 ok(count == 1, "Unexpected attribute count %u.\n", count);
917 value = 0;
918 hr = IMFAttributes_GetUINT32(attributes2, &MF_SA_D3D_AWARE, &value);
919 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
920 ok(value == 1, "Unexpected value %d.\n", value);
922 IMFAttributes_Release(attributes2);
924 hr = IMFAttributes_GetCount(attributes, &count);
925 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
926 ok(count == 1, "Unexpected attribute count %u.\n", count);
928 memset(&rect, 0, sizeof(rect));
929 hr = IMFAttributes_GetBlob(attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&rect, sizeof(rect), NULL);
930 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
931 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
932 "Unexpected zoom rect (%f, %f) - (%f, %f).\n", rect.left, rect.top, rect.right, rect.bottom);
934 IMFAttributes_Release(attributes);
936 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
937 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
939 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
940 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
941 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
943 IMFVideoDeviceID_Release(deviceid);
945 /* Stream configuration. */
946 input_count = output_count = 0;
947 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
948 ok(hr == S_OK, "Failed to get stream count, hr %#lx.\n", hr);
949 ok(input_count == 1 && output_count == 1, "Unexpected stream count %lu/%lu.\n", input_count, output_count);
951 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
952 ok(hr == S_OK, "Failed to get stream limits, hr %#lx.\n", hr);
953 ok(input_min == 1 && input_max == 16 && output_min == 1 && output_max == 1, "Unexpected stream limits %lu/%lu, %lu/%lu.\n",
954 input_min, input_max, output_min, output_max);
956 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
957 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
959 hr = IMFTransform_GetOutputStreamInfo(transform, 1, &output_info);
960 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
962 memset(&input_info, 0xcc, sizeof(input_info));
963 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
964 ok(hr == S_OK, "Failed to get input info, hr %#lx.\n", hr);
966 memset(&output_info, 0xcc, sizeof(output_info));
967 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
968 ok(hr == S_OK, "Failed to get input info, hr %#lx.\n", hr);
969 ok(!(output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)),
970 "Unexpected output flags %#lx.\n", output_info.dwFlags);
972 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
973 ok(hr == S_OK, "Failed to get input info, hr %#lx.\n", hr);
974 ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
976 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
977 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
979 hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
980 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
982 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
983 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
985 hr = IMFTransform_AddInputStreams(transform, 16, NULL);
986 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
988 hr = IMFTransform_AddInputStreams(transform, 16, ids);
989 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
991 memset(ids, 0, sizeof(ids));
992 hr = IMFTransform_AddInputStreams(transform, 15, ids);
993 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
995 for (i = 0; i < ARRAY_SIZE(ids); ++i)
996 ids[i] = i + 1;
998 hr = IMFTransform_AddInputStreams(transform, 15, ids);
999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1001 input_count = output_count = 0;
1002 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
1003 ok(hr == S_OK, "Failed to get stream count, hr %#lx.\n", hr);
1004 ok(input_count == 16 && output_count == 1, "Unexpected stream count %lu/%lu.\n", input_count, output_count);
1006 memset(&input_info, 0, sizeof(input_info));
1007 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
1008 ok(hr == S_OK, "Failed to get input info, hr %#lx.\n", hr);
1009 ok((input_info.dwFlags & (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL)) ==
1010 (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL), "Unexpected flags %#lx.\n", input_info.dwFlags);
1012 attributes = NULL;
1013 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
1014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1015 hr = IMFAttributes_GetCount(attributes, &count);
1016 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1017 ok(count == 1, "Unexpected count %u.\n", count);
1018 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &count);
1019 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1020 ok(count == 1, "Unexpected count %u.\n", count);
1021 ok(!!attributes, "Unexpected attributes.\n");
1023 attributes2 = NULL;
1024 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
1025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1026 ok(attributes == attributes2, "Unexpected instance.\n");
1028 IMFAttributes_Release(attributes2);
1029 IMFAttributes_Release(attributes);
1031 attributes = NULL;
1032 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
1033 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1034 ok(!!attributes, "Unexpected attributes.\n");
1035 IMFAttributes_Release(attributes);
1037 hr = IMFTransform_DeleteInputStream(transform, 0);
1038 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
1040 hr = IMFTransform_DeleteInputStream(transform, 1);
1041 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1043 input_count = output_count = 0;
1044 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
1045 ok(hr == S_OK, "Failed to get stream count, hr %#lx.\n", hr);
1046 ok(input_count == 15 && output_count == 1, "Unexpected stream count %lu/%lu.\n", input_count, output_count);
1048 IMFTransform_Release(transform);
1050 hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
1051 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1053 hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
1054 ok(hr == S_OK, "Failed to create default mixer, hr %#lx.\n", hr);
1055 IMFTransform_Release(transform);
1058 static void test_surface_sample(void)
1060 IDirect3DSurface9 *backbuffer = NULL, *surface;
1061 DWORD flags, buffer_count, length;
1062 IMFDesiredSample *desired_sample;
1063 IMFMediaBuffer *buffer, *buffer2;
1064 LONGLONG duration, time1, time2;
1065 IDirect3DSwapChain9 *swapchain;
1066 IDirect3DDevice9 *device;
1067 IMFSample *sample;
1068 IUnknown *unk;
1069 UINT32 count;
1070 HWND window;
1071 HRESULT hr;
1072 BYTE *data;
1074 window = create_window();
1075 if (!(device = create_device(window)))
1077 skip("Failed to create a D3D device, skipping tests.\n");
1078 goto done;
1081 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
1082 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1084 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
1085 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1086 ok(backbuffer != NULL, "The back buffer is NULL\n");
1088 IDirect3DSwapChain9_Release(swapchain);
1090 hr = MFCreateVideoSampleFromSurface(NULL, &sample);
1091 ok(hr == S_OK, "Failed to create surface sample, hr %#lx.\n", hr);
1092 IMFSample_Release(sample);
1094 hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample);
1095 ok(hr == S_OK, "Failed to create surface sample, hr %#lx.\n", hr);
1097 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
1098 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1099 IUnknown_Release(unk);
1101 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired_sample);
1102 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1104 hr = IMFSample_GetCount(sample, &count);
1105 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1106 ok(!count, "Unexpected attribute count %u.\n", count);
1108 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, NULL);
1109 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1111 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, &time2);
1112 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1114 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, NULL);
1115 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1117 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
1118 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1120 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 123, 456);
1122 time1 = time2 = 0;
1123 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
1124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1125 ok(time1 == 123 && time2 == 456, "Unexpected time values.\n");
1127 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 0, 0);
1129 time1 = time2 = 1;
1130 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
1131 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1132 ok(time1 == 0 && time2 == 0, "Unexpected time values.\n");
1134 IMFDesiredSample_Clear(desired_sample);
1136 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
1137 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1139 hr = IMFSample_GetCount(sample, &count);
1140 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1141 ok(!count, "Unexpected attribute count %u.\n", count);
1143 /* Attributes are cleared. */
1144 hr = IMFSample_SetUnknown(sample, &MFSampleExtension_Token, NULL);
1145 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1147 hr = IMFSample_GetCount(sample, &count);
1148 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1149 ok(count == 1, "Unexpected attribute count %u.\n", count);
1151 hr = IMFSample_SetSampleTime(sample, 0);
1152 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1154 hr = IMFSample_GetSampleTime(sample, &time1);
1155 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1157 hr = IMFSample_SetSampleDuration(sample, 0);
1158 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1160 hr = IMFSample_GetSampleDuration(sample, &duration);
1161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1163 hr = IMFSample_SetSampleFlags(sample, 0x1);
1164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1166 IMFDesiredSample_Clear(desired_sample);
1168 hr = IMFSample_GetCount(sample, &count);
1169 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1170 ok(!count, "Unexpected attribute count %u.\n", count);
1172 hr = IMFSample_GetSampleTime(sample, &time1);
1173 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
1175 hr = IMFSample_GetSampleDuration(sample, &duration);
1176 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
1178 hr = IMFSample_GetSampleFlags(sample, &flags);
1179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1180 ok(!flags, "Unexpected flags %#lx.\n", flags);
1182 IMFDesiredSample_Release(desired_sample);
1184 hr = IMFSample_GetCount(sample, &count);
1185 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
1186 ok(!count, "Unexpected attribute count.\n");
1188 buffer_count = 0;
1189 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1190 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1191 ok(buffer_count == 1, "Unexpected attribute count.\n");
1193 hr = IMFSample_GetTotalLength(sample, &length);
1194 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
1195 ok(!length, "Unexpected length %lu.\n", length);
1197 hr = IMFSample_GetSampleDuration(sample, &duration);
1198 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
1200 hr = IMFSample_GetSampleTime(sample, &duration);
1201 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
1203 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1204 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1206 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1207 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1209 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1210 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
1211 ok(!length, "Unexpected length %lu.\n", length);
1213 hr = IMFMediaBuffer_SetCurrentLength(buffer, 16);
1214 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
1216 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1217 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
1218 ok(length == 16, "Unexpected length %lu.\n", length);
1220 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1221 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1223 hr = IMFMediaBuffer_Unlock(buffer);
1224 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1226 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk);
1227 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1229 hr = IMFSample_AddBuffer(sample, buffer);
1230 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1232 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1233 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1234 ok(buffer_count == 2, "Unexpected buffer count.\n");
1236 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1237 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1239 hr = IMFSample_CopyToBuffer(sample, buffer);
1240 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1242 hr = IMFSample_RemoveAllBuffers(sample);
1243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1245 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1246 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1247 ok(!buffer_count, "Unexpected buffer count.\n");
1249 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1250 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1251 ok(surface == backbuffer, "Unexpected instance.\n");
1252 IDirect3DSurface9_Release(surface);
1254 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IUnknown, (void **)&surface);
1255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1256 ok(surface == backbuffer, "Unexpected instance.\n");
1257 IDirect3DSurface9_Release(surface);
1259 IMFMediaBuffer_Release(buffer);
1261 hr = IMFSample_GetSampleFlags(sample, &flags);
1262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1264 hr = IMFSample_SetSampleFlags(sample, 0x123);
1265 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1267 flags = 0;
1268 hr = IMFSample_GetSampleFlags(sample, &flags);
1269 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1270 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
1272 IMFSample_Release(sample);
1273 if (backbuffer)
1274 IDirect3DSurface9_Release(backbuffer);
1275 ok(!IDirect3DDevice9_Release(device), "Unexpected refcount.\n");
1277 done:
1278 DestroyWindow(window);
1281 static void test_default_mixer_type_negotiation(void)
1283 IMFMediaType *media_type, *media_type2;
1284 IDirect3DDeviceManager9 *manager;
1285 DXVA2_VideoProcessorCaps caps;
1286 IMFVideoProcessor *processor;
1287 GUID subtype, guid, *guids;
1288 IDirect3DDevice9 *device;
1289 IMFMediaType *video_type;
1290 IMFTransform *transform;
1291 MFVideoArea aperture;
1292 UINT count, token;
1293 IUnknown *unk;
1294 DWORD index;
1295 HWND window;
1296 HRESULT hr;
1298 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
1299 ok(hr == S_OK, "Failed to create default mixer, hr %#lx.\n", hr);
1301 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&processor);
1302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1304 hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
1305 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1307 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1308 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1310 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1311 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1313 hr = MFCreateMediaType(&media_type);
1314 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
1316 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1317 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1319 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1320 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1322 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1323 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
1325 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
1326 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
1328 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1329 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1331 /* Now try with device manager. */
1333 window = create_window();
1334 if (!(device = create_device(window)))
1336 skip("Failed to create a D3D device, skipping tests.\n");
1337 goto done;
1340 hr = IMFTransform_SetInputType(transform, 0, NULL, 0);
1341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1342 hr = IMFTransform_SetInputType(transform, 0, NULL, MFT_SET_TYPE_TEST_ONLY);
1343 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1345 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
1346 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1348 hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
1349 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1351 /* Now manager is not initialized. */
1352 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1353 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
1355 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
1356 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
1358 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1361 /* And now type description is incomplete. */
1362 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1363 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
1364 IMFMediaType_Release(media_type);
1366 video_type = create_video_type(&MFVideoFormat_RGB32);
1368 /* Partially initialized type. */
1369 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1370 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
1372 /* Only required data - frame size and uncompressed marker. */
1373 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1374 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1375 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1376 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1377 memset(&aperture, 0, sizeof(aperture));
1378 aperture.Area.cx = 100; aperture.Area.cy = 200;
1379 hr = IMFMediaType_SetBlob(video_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture));
1380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1381 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, 2);
1382 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1384 hr = IMFTransform_SetInputType(transform, 0, video_type, MFT_SET_TYPE_TEST_ONLY);
1385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1387 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1388 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1390 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1391 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1393 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1394 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1396 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1398 ok(media_type == video_type, "Unexpected media type instance.\n");
1400 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
1401 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1402 ok(media_type == media_type2, "Unexpected media type instance.\n");
1403 IMFMediaType_Release(media_type);
1404 IMFMediaType_Release(media_type2);
1406 /* Modified after type was set. */
1407 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, (UINT64)56 << 32 | 55);
1408 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1410 /* Check attributes on available output types. */
1411 index = 0;
1412 while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
1414 UINT64 frame_size, ratio;
1415 MFVideoArea aperture;
1416 GUID subtype, major;
1417 UINT32 value;
1419 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &major);
1420 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1421 ok(IsEqualGUID(&major, &MFMediaType_Video), "Unexpected major type.\n");
1422 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
1423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1424 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size);
1425 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1426 ok(frame_size == ((UINT64)100 << 32 | 200), "Unexpected frame size %s.\n", wine_dbgstr_longlong(frame_size));
1427 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
1428 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1429 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value);
1430 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1431 ok(value == MFVideoInterlace_Progressive, "Unexpected interlace mode.\n");
1432 /* Ratio from input type */
1433 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
1434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1435 ok(ratio == ((UINT64)1 << 32 | 1), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
1436 hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
1437 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1438 ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
1439 hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
1440 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1441 ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
1442 hr = IMFMediaType_GetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
1443 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1444 ok(value == 2, "Unexpected value %u.\n", value);
1446 IMFMediaType_Release(media_type);
1448 ok(index > 1, "Unexpected number of available types.\n");
1450 hr = IMFMediaType_DeleteItem(video_type, &MF_MT_FIXED_SIZE_SAMPLES);
1451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1453 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1454 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1456 index = 0;
1457 while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
1459 UINT32 value;
1460 UINT64 ratio;
1462 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
1463 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1464 ok(ratio == ((UINT64)56 << 32 | 55), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
1466 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
1467 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1468 ok(value == 1, "Unexpected value %u.\n", value);
1470 IMFMediaType_Release(media_type);
1472 ok(index > 1, "Unexpected number of available types.\n");
1474 /* Cloned type is returned. */
1475 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1477 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type2);
1478 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1479 ok(media_type != media_type2, "Unexpected media type instance.\n");
1480 IMFMediaType_Release(media_type);
1481 IMFMediaType_Release(media_type2);
1483 /* Minimal valid attribute set for output type. */
1484 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1487 hr = MFCreateMediaType(&media_type2);
1488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1490 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
1491 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1493 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1494 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1495 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &subtype);
1496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1498 hr = IMFTransform_SetOutputType(transform, 1, NULL, MFT_SET_TYPE_TEST_ONLY);
1499 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
1501 hr = IMFTransform_SetOutputType(transform, 0, NULL, MFT_SET_TYPE_TEST_ONLY);
1502 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1504 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1505 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
1507 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1510 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1511 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1513 /* Candidate type have frame size set, mismatching size is accepted. */
1514 hr = IMFMediaType_SetUINT64(media_type2, &MF_MT_FRAME_SIZE, (UINT64)64 << 32 | 64);
1515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1517 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1520 IMFMediaType_Release(media_type2);
1521 IMFMediaType_Release(media_type);
1523 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1524 todo_wine
1525 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1527 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
1528 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1530 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1531 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1532 ok(media_type == video_type, "Unexpected pointer.\n");
1533 hr = IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&unk);
1534 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1535 IUnknown_Release(unk);
1536 IMFMediaType_Release(media_type);
1538 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1539 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1541 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1542 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1544 hr = IMFTransform_SetOutputType(transform, 1, media_type, 0);
1545 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
1547 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
1548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1550 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1551 todo_wine
1552 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1554 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1556 ok(count > 0 && !!guids, "Unexpected modes data.\n");
1557 CoTaskMemFree(guids);
1559 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
1560 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1562 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
1563 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1564 ok(media_type == media_type2, "Unexpected media type instance.\n");
1566 IMFMediaType_Release(media_type);
1568 /* Clear input types */
1569 hr = IMFTransform_SetInputType(transform, 0, NULL, MFT_SET_TYPE_TEST_ONLY);
1570 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1572 hr = IMFTransform_SetInputType(transform, 0, NULL, 0);
1573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1574 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1575 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1576 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
1577 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1579 /* Restore types */
1580 hr = IMFTransform_SetOutputType(transform, 0, media_type2, 0);
1581 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
1582 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
1583 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
1585 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1587 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1588 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1589 ok(media_type == video_type, "Unexpected media type instance.\n");
1590 IMFMediaType_Release(media_type);
1592 hr = IMFTransform_SetOutputType(transform, 0, media_type2, 0);
1593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1594 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
1595 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1596 ok(media_type2 == media_type, "Unexpected media type instance.\n");
1598 IMFMediaType_Release(media_type2);
1599 IMFMediaType_Release(media_type);
1601 /* Resetting type twice */
1602 hr = IMFTransform_SetInputType(transform, 0, NULL, 0);
1603 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1604 hr = IMFTransform_SetInputType(transform, 0, NULL, 0);
1605 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1607 IMFVideoProcessor_Release(processor);
1609 IMFMediaType_Release(video_type);
1611 IDirect3DDeviceManager9_Release(manager);
1613 IDirect3DDevice9_Release(device);
1615 done:
1616 IMFTransform_Release(transform);
1617 DestroyWindow(window);
1620 static void test_default_presenter(void)
1622 IMFVideoDisplayControl *display_control;
1623 IMFVideoPresenter *presenter;
1624 IMFRateSupport *rate_support;
1625 IDirect3DDeviceManager9 *dm;
1626 IMFVideoDeviceID *deviceid;
1627 IUnknown *unk, *unk2;
1628 HWND hwnd, hwnd2;
1629 DWORD flags;
1630 float rate;
1631 HRESULT hr;
1632 GUID iid;
1634 hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter);
1635 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1637 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1638 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
1640 check_interface(presenter, &IID_IQualProp, TRUE);
1641 check_interface(presenter, &IID_IMFVideoPositionMapper, TRUE);
1642 check_interface(presenter, &IID_IMFTopologyServiceLookupClient, TRUE);
1643 check_interface(presenter, &IID_IMFVideoDisplayControl, TRUE);
1644 check_interface(presenter, &IID_IMFRateSupport, TRUE);
1645 check_interface(presenter, &IID_IMFGetService, TRUE);
1646 check_interface(presenter, &IID_IMFClockStateSink, TRUE);
1647 check_interface(presenter, &IID_IMFVideoPresenter, TRUE);
1648 check_interface(presenter, &IID_IMFVideoDeviceID, TRUE);
1649 check_interface(presenter, &IID_IMFQualityAdvise, TRUE);
1650 check_interface(presenter, &IID_IDirect3DDeviceManager9, TRUE);
1651 check_interface(presenter, &IID_IMFQualityAdviseLimits, TRUE);
1652 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
1653 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, TRUE);
1654 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPresenter, TRUE);
1655 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFClockStateSink, TRUE);
1656 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTopologyServiceLookupClient, TRUE);
1657 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IQualProp, TRUE);
1658 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFRateSupport, TRUE);
1659 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFGetService, TRUE);
1660 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDeviceID, TRUE);
1661 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdvise, TRUE);
1662 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdviseLimits, TRUE);
1663 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTransform, FALSE);
1664 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1665 check_service_interface(presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1667 /* Query arbitrary supported interface back from device manager wrapper. */
1668 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IDirect3DDeviceManager9, (void **)&dm);
1669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1670 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IQualProp, (void **)&unk);
1671 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1672 IUnknown_Release(unk);
1673 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IUnknown, (void **)&unk);
1674 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1675 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IUnknown, (void **)&unk2);
1676 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1677 ok(unk == unk2, "Unexpected interface.\n");
1678 IUnknown_Release(unk2);
1679 IUnknown_Release(unk);
1680 IDirect3DDeviceManager9_Release(dm);
1682 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_MIXER_SERVICE, &IID_IUnknown, (void **)&unk);
1683 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#lx.\n", hr);
1685 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
1686 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1688 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
1689 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1691 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
1692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1693 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
1695 IMFVideoDeviceID_Release(deviceid);
1697 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
1698 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1700 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, NULL);
1701 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1703 flags = 123;
1704 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
1705 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1706 ok(!flags, "Unexpected rendering flags %#lx.\n", flags);
1708 IMFVideoDisplayControl_Release(display_control);
1710 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1711 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1712 IDirect3DDeviceManager9_Release(dm);
1714 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1717 /* Video window */
1718 hwnd = create_window();
1719 ok(!!hwnd, "Failed to create a test window.\n");
1721 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, NULL);
1722 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
1724 hwnd2 = hwnd;
1725 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1726 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1727 ok(hwnd2 == NULL, "Unexpected window %p.\n", hwnd2);
1729 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, NULL);
1730 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1732 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, (HWND)0x1);
1733 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1735 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1736 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1738 hwnd2 = NULL;
1739 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1740 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1741 ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
1742 IMFVideoDisplayControl_Release(display_control);
1744 /* Rate support. */
1745 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
1746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1748 rate = 1.0f;
1749 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1750 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1751 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1753 rate = 1.0f;
1754 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1755 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1756 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1758 rate = 1.0f;
1759 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1760 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1761 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1763 rate = 1.0f;
1764 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1766 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1768 IMFRateSupport_Release(rate_support);
1770 ok(!IMFVideoPresenter_Release(presenter), "Unexpected refcount.\n");
1772 DestroyWindow(hwnd);
1775 static void test_MFCreateVideoMixerAndPresenter(void)
1777 IUnknown *mixer, *presenter;
1778 HRESULT hr;
1780 hr = MFCreateVideoMixerAndPresenter(NULL, NULL, &IID_IUnknown, (void **)&mixer, &IID_IUnknown, (void **)&presenter);
1781 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1783 IUnknown_Release(mixer);
1784 IUnknown_Release(presenter);
1787 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
1788 REFIID riid, void **obj)
1790 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
1791 IsEqualIID(riid, &IID_IUnknown))
1793 *obj = iface;
1794 IMFVideoSampleAllocatorNotify_AddRef(iface);
1795 return S_OK;
1798 *obj = NULL;
1799 return E_NOINTERFACE;
1802 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
1804 return 2;
1807 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
1809 return 1;
1812 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
1814 return E_NOTIMPL;
1817 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
1819 test_notify_callback_QueryInterface,
1820 test_notify_callback_AddRef,
1821 test_notify_callback_Release,
1822 test_notify_callback_NotifyRelease,
1825 static void test_MFCreateVideoSampleAllocator(void)
1827 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
1828 IMFVideoSampleAllocatorCallback *allocator_cb;
1829 IMFMediaType *media_type, *video_type;
1830 IMFVideoSampleAllocator *allocator;
1831 IDirect3DDeviceManager9 *manager;
1832 IMFSample *sample, *sample2;
1833 IDirect3DSurface9 *surface;
1834 IDirect3DDevice9 *device;
1835 IMFMediaBuffer *buffer;
1836 LONG refcount, count;
1837 unsigned int token;
1838 IMFGetService *gs;
1839 IUnknown *unk;
1840 HWND window;
1841 HRESULT hr;
1842 BYTE *data;
1844 hr = MFCreateVideoSampleAllocator(&IID_IUnknown, (void **)&unk);
1845 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1846 IUnknown_Release(unk);
1848 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1849 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1851 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
1852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1854 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1855 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1857 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
1858 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1860 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1861 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1863 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
1864 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1866 count = 10;
1867 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1868 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1869 ok(!count, "Unexpected count %ld.\n", count);
1871 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
1872 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1874 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1875 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
1877 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
1878 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1880 hr = MFCreateMediaType(&media_type);
1881 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1883 /* It expects IMFVideoMediaType aka video major type. Exact return code is E_NOINTERFACE,
1884 likely coming from querying for IMFVideoMediaType. Does not seem valuable to match it. */
1885 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
1886 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
1888 video_type = create_video_type(&MFVideoFormat_RGB32);
1890 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
1891 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
1893 /* Frame size is required. */
1894 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1895 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1896 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1897 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1899 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1900 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1901 ok(count == 1, "Unexpected count %ld.\n", count);
1903 sample = NULL;
1904 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1905 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1906 refcount = get_refcount(sample);
1908 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
1909 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
1911 /* Reinitialize with active sample. */
1912 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 4, video_type);
1913 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1914 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
1916 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1918 ok(count == 4, "Unexpected count %ld.\n", count);
1920 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1921 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1923 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1924 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1926 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1928 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
1929 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#lx.\n", hr);
1931 /* Device manager wasn't set, sample gets regular memory buffers. */
1932 if (SUCCEEDED(hr))
1934 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1935 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
1936 IMFGetService_Release(gs);
1939 IMFMediaBuffer_Release(buffer);
1941 IMFSample_Release(sample);
1943 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
1945 IMFVideoSampleAllocator_Release(allocator);
1947 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocatorCallback, (void **)&unk);
1948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1949 IUnknown_Release(unk);
1951 /* Using device manager */
1952 window = create_window();
1953 if (!(device = create_device(window)))
1955 skip("Failed to create a D3D device, skipping tests.\n");
1956 IMFMediaType_Release(video_type);
1957 IMFMediaType_Release(media_type);
1958 DestroyWindow(window);
1959 return;
1962 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
1963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1964 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1965 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
1967 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1968 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1970 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
1971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1973 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1974 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1975 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1976 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1978 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1981 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1982 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1984 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1985 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1987 check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE);
1988 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1989 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
1991 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1994 hr = IMFMediaBuffer_Unlock(buffer);
1995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1997 IMFMediaBuffer_Release(buffer);
1998 IMFSample_Release(sample);
1999 IMFVideoSampleAllocator_Release(allocator);
2000 IMFMediaType_Release(video_type);
2001 IMFMediaType_Release(media_type);
2002 IDirect3DDeviceManager9_Release(manager);
2003 IDirect3DDevice9_Release(device);
2004 DestroyWindow(window);
2007 struct test_host
2009 IMFTopologyServiceLookup IMFTopologyServiceLookup_iface;
2010 IMediaEventSink IMediaEventSink_iface;
2011 IMFTransform *mixer;
2012 IMFVideoPresenter *presenter;
2015 static struct test_host *impl_from_test_host(IMFTopologyServiceLookup *iface)
2017 return CONTAINING_RECORD(iface, struct test_host, IMFTopologyServiceLookup_iface);
2020 static struct test_host *impl_from_test_host_events(IMediaEventSink *iface)
2022 return CONTAINING_RECORD(iface, struct test_host, IMediaEventSink_iface);
2025 static HRESULT WINAPI test_host_QueryInterface(IMFTopologyServiceLookup *iface, REFIID riid, void **obj)
2027 if (IsEqualIID(riid, &IID_IMFTopologyServiceLookup) ||
2028 IsEqualIID(riid, &IID_IUnknown))
2030 *obj = iface;
2031 IMFTopologyServiceLookup_AddRef(iface);
2032 return S_OK;
2035 *obj = NULL;
2036 return E_NOINTERFACE;
2039 static ULONG WINAPI test_host_AddRef(IMFTopologyServiceLookup *iface)
2041 return 2;
2044 static ULONG WINAPI test_host_Release(IMFTopologyServiceLookup *iface)
2046 return 1;
2049 static HRESULT WINAPI test_host_LookupService(IMFTopologyServiceLookup *iface,
2050 MF_SERVICE_LOOKUP_TYPE lookup_type, DWORD index, REFGUID service,
2051 REFIID riid, void **objects, DWORD *num_objects)
2053 struct test_host *host = impl_from_test_host(iface);
2055 ok(*num_objects == 1, "Unexpected number of requested objects %lu\n", *num_objects);
2057 memset(objects, 0, *num_objects * sizeof(*objects));
2059 if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
2061 if (IsEqualIID(riid, &IID_IMFClock)) return E_FAIL;
2062 if (IsEqualIID(riid, &IID_IMediaEventSink))
2064 *objects = &host->IMediaEventSink_iface;
2065 IMediaEventSink_AddRef(&host->IMediaEventSink_iface);
2066 return S_OK;
2069 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
2070 return E_UNEXPECTED;
2073 if (IsEqualGUID(service, &MR_VIDEO_MIXER_SERVICE))
2075 if (IsEqualIID(riid, &IID_IMFTransform))
2077 *objects = host->mixer;
2078 IMFTransform_AddRef(host->mixer);
2079 return S_OK;
2081 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
2082 return E_UNEXPECTED;
2085 return E_NOTIMPL;
2088 static const IMFTopologyServiceLookupVtbl test_host_vtbl =
2090 test_host_QueryInterface,
2091 test_host_AddRef,
2092 test_host_Release,
2093 test_host_LookupService,
2096 static HRESULT WINAPI test_host_events_QueryInterface(IMediaEventSink *iface, REFIID riid, void **obj)
2098 struct test_host *host = impl_from_test_host_events(iface);
2099 return IMFTopologyServiceLookup_QueryInterface(&host->IMFTopologyServiceLookup_iface, riid, obj);
2102 static ULONG WINAPI test_host_events_AddRef(IMediaEventSink *iface)
2104 struct test_host *host = impl_from_test_host_events(iface);
2105 return IMFTopologyServiceLookup_AddRef(&host->IMFTopologyServiceLookup_iface);
2108 static ULONG WINAPI test_host_events_Release(IMediaEventSink *iface)
2110 struct test_host *host = impl_from_test_host_events(iface);
2111 return IMFTopologyServiceLookup_Release(&host->IMFTopologyServiceLookup_iface);
2114 static HRESULT WINAPI test_host_events_Notify(IMediaEventSink *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2116 return S_OK;
2119 static const IMediaEventSinkVtbl test_host_events_vtbl =
2121 test_host_events_QueryInterface,
2122 test_host_events_AddRef,
2123 test_host_events_Release,
2124 test_host_events_Notify,
2127 static void init_test_host(struct test_host *host, IMFTransform *mixer, IMFVideoPresenter *presenter)
2129 host->IMFTopologyServiceLookup_iface.lpVtbl = &test_host_vtbl;
2130 host->IMediaEventSink_iface.lpVtbl = &test_host_events_vtbl;
2131 /* No need to keep references. */
2132 host->mixer = mixer;
2133 host->presenter = presenter;
2136 static void test_presenter_video_position(void)
2138 IMFTopologyServiceLookupClient *lookup_client;
2139 IMFVideoDisplayControl *display_control;
2140 IMFAttributes *mixer_attributes;
2141 MFVideoNormalizedRect src_rect;
2142 IMFVideoPresenter *presenter;
2143 struct test_host host;
2144 IMFTransform *mixer;
2145 RECT dst_rect;
2146 UINT32 count;
2147 HRESULT hr;
2148 HWND hwnd;
2150 hwnd = create_window();
2151 ok(!!hwnd, "Failed to create a test window.\n");
2153 /* Setting position without the mixer. */
2154 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2155 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2156 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2157 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2159 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2160 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
2161 SetRect(&dst_rect, 0, 0, 10, 10);
2162 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2163 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2164 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
2165 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2167 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2168 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
2169 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2170 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2172 IMFVideoDisplayControl_Release(display_control);
2173 IMFVideoPresenter_Release(presenter);
2175 /* With the mixer. */
2176 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2177 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
2179 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2180 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2182 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2183 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2185 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2186 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2188 init_test_host(&host, mixer, presenter);
2190 /* Clear default mixer attributes, then attach presenter. */
2191 hr = IMFTransform_GetAttributes(mixer, &mixer_attributes);
2192 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2194 hr = IMFAttributes_DeleteAllItems(mixer_attributes);
2195 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2197 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
2198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2200 hr = IMFAttributes_GetCount(mixer_attributes, &count);
2201 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2202 ok(count == 1, "Unexpected count %u.\n", count);
2204 memset(&src_rect, 0, sizeof(src_rect));
2205 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
2206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2207 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
2208 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
2210 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &dst_rect);
2211 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2213 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, NULL);
2214 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2216 SetRect(&dst_rect, 1, 2, 3, 4);
2217 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
2218 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2219 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
2220 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
2221 ok(dst_rect.left == 0 && dst_rect.right == 0 && dst_rect.top == 0 && dst_rect.bottom == 0,
2222 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
2224 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, NULL);
2225 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2227 /* Setting position requires a window. */
2228 SetRect(&dst_rect, 0, 0, 10, 10);
2229 memset(&src_rect, 0, sizeof(src_rect));
2230 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, &dst_rect);
2231 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2233 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
2234 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2236 SetRect(&dst_rect, 0, 0, 10, 10);
2237 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2238 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2240 SetRect(&dst_rect, 1, 2, 3, 4);
2241 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
2242 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2243 ok(dst_rect.left == 0 && dst_rect.right == 10 && dst_rect.top == 0 && dst_rect.bottom == 10,
2244 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
2246 set_rect(&src_rect, 0.0f, 0.0f, 2.0f, 1.0f);
2247 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
2248 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2250 set_rect(&src_rect, -0.1f, 0.0f, 0.9f, 1.0f);
2251 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
2252 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2254 /* Flipped source rectangle. */
2255 set_rect(&src_rect, 0.5f, 0.0f, 0.4f, 1.0f);
2256 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
2257 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2259 set_rect(&src_rect, 0.0f, 0.5f, 0.4f, 0.1f);
2260 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
2261 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2263 set_rect(&src_rect, 0.1f, 0.2f, 0.8f, 0.9f);
2264 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
2265 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2267 /* Presenter updates mixer attribute. */
2268 memset(&src_rect, 0, sizeof(src_rect));
2269 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
2270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2271 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
2272 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
2274 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
2275 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2276 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
2277 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
2279 SetRect(&dst_rect, 1, 2, 999, 1000);
2280 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2281 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2283 SetRect(&dst_rect, 0, 1, 3, 4);
2284 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
2285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2286 ok(dst_rect.left == 1 && dst_rect.right == 999 && dst_rect.top == 2 && dst_rect.bottom == 1000,
2287 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
2289 /* Flipped destination rectangle. */
2290 SetRect(&dst_rect, 100, 1, 50, 1000);
2291 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2292 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2294 SetRect(&dst_rect, 1, 100, 100, 50);
2295 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
2296 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2298 IMFVideoDisplayControl_Release(display_control);
2300 IMFTopologyServiceLookupClient_Release(lookup_client);
2301 IMFVideoPresenter_Release(presenter);
2302 IMFAttributes_Release(mixer_attributes);
2303 IMFTransform_Release(mixer);
2305 DestroyWindow(hwnd);
2308 static void test_presenter_native_video_size(void)
2310 IMFTopologyServiceLookupClient *lookup_client;
2311 IMFVideoDisplayControl *display_control;
2312 IMFVideoPresenter *presenter;
2313 struct test_host host;
2314 IMFTransform *mixer;
2315 SIZE size, ratio;
2316 HRESULT hr;
2317 IMFMediaType *video_type;
2318 IDirect3DDeviceManager9 *dm;
2320 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2321 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
2323 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2324 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2326 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2327 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2328 IMFTopologyServiceLookupClient_Release(lookup_client);
2330 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2331 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2333 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, NULL);
2334 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2336 memset(&size, 0xcc, sizeof(size));
2337 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, NULL);
2338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2339 ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n");
2341 memset(&ratio, 0xcc, sizeof(ratio));
2342 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, &ratio);
2343 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2344 ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n");
2346 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2349 /* Configure mixer primary stream. */
2350 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
2351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2353 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)dm);
2354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2356 IDirect3DDeviceManager9_Release(dm);
2358 video_type = create_video_type(&MFVideoFormat_RGB32);
2360 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
2361 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2362 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2363 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2365 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
2366 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2368 /* Native video size is cached on initialization. */
2369 init_test_host(&host, mixer, presenter);
2371 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
2372 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2374 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
2375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2376 ok(size.cx == 640 && size.cy == 480, "Unexpected size %lu x %lu.\n", size.cx, size.cy);
2377 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
2378 "Unexpected ratio %lu x %lu.\n", ratio.cx, ratio.cy);
2380 /* Update input type. */
2381 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)320 << 32 | 240);
2382 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2384 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
2385 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2387 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
2388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2389 ok(size.cx == 640 && size.cy == 480, "Unexpected size %lu x %lu.\n", size.cx, size.cy);
2390 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
2391 "Unexpected ratio %lu x %lu.\n", ratio.cx, ratio.cy);
2393 /* Negotiating types updates native video size. */
2394 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2395 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2397 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
2398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2399 ok(size.cx == 320 && size.cy == 240, "Unexpected size %lu x %lu.\n", size.cx, size.cy);
2400 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
2401 "Unexpected ratio %lu x %lu.\n", ratio.cx, ratio.cy);
2403 IMFTopologyServiceLookupClient_Release(lookup_client);
2404 IMFMediaType_Release(video_type);
2405 IMFVideoDisplayControl_Release(display_control);
2406 IMFVideoPresenter_Release(presenter);
2407 IMFTransform_Release(mixer);
2410 static void test_presenter_ar_mode(void)
2412 IMFVideoDisplayControl *display_control;
2413 HRESULT hr;
2414 DWORD mode;
2416 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
2417 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2419 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, NULL);
2420 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2422 mode = 0;
2423 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2424 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2425 ok(mode == (MFVideoARMode_PreservePicture | MFVideoARMode_PreservePixel), "Unexpected mode %#lx.\n", mode);
2427 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, 0x100);
2428 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2430 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_Mask);
2431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2433 mode = 0;
2434 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2435 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2436 ok(mode == MFVideoARMode_Mask, "Unexpected mode %#lx.\n", mode);
2438 IMFVideoDisplayControl_Release(display_control);
2441 static void test_presenter_video_window(void)
2443 D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
2444 IMFVideoDisplayControl *display_control;
2445 IDirect3DDeviceManager9 *dm;
2446 IDirect3DDevice9 *d3d_device;
2447 HANDLE hdevice;
2448 HRESULT hr;
2449 IDirect3DSwapChain9 *swapchain;
2450 D3DPRESENT_PARAMETERS present_params = { 0 };
2451 HWND window;
2453 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
2454 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2456 hr = MFGetService((IUnknown *)display_control, &MR_VIDEO_ACCELERATION_SERVICE,
2457 &IID_IDirect3DDeviceManager9, (void **)&dm);
2459 hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &hdevice);
2460 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2462 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
2463 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2465 hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
2466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2467 ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
2469 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
2470 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2472 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
2473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2475 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
2476 ok(present_params.Windowed, "Unexpected windowed mode.\n");
2477 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
2478 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#lx.\n", present_params.Flags);
2479 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
2481 IDirect3DSwapChain9_Release(swapchain);
2482 IDirect3DDevice9_Release(d3d_device);
2484 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
2485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2487 /* Setting window. */
2488 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window);
2489 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2490 ok(!window, "Unexpected window %p.\n", window);
2492 window = create_window();
2494 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2495 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2497 /* Device is not recreated or reset on window change. */
2498 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
2499 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2501 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
2502 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2504 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
2505 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2507 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
2508 ok(present_params.Windowed, "Unexpected windowed mode.\n");
2509 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
2510 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#lx.\n", present_params.Flags);
2511 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
2513 IDirect3DSwapChain9_Release(swapchain);
2514 IDirect3DDevice9_Release(d3d_device);
2516 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
2517 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2519 hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, hdevice);
2520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2522 IDirect3DDeviceManager9_Release(dm);
2523 ok(!IMFVideoDisplayControl_Release(display_control), "Unexpected refcount.\n");
2525 DestroyWindow(window);
2528 static void test_presenter_quality_control(void)
2530 IMFQualityAdviseLimits *qa_limits;
2531 IMFVideoPresenter *presenter;
2532 MF_QUALITY_DROP_MODE mode;
2533 IMFQualityAdvise *advise;
2534 MF_QUALITY_LEVEL level;
2535 IQualProp *qual_prop;
2536 int frame_count;
2537 HRESULT hr;
2539 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2540 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2542 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdviseLimits, (void **)&qa_limits);
2543 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2545 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdvise, (void **)&advise);
2546 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2548 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, NULL);
2549 todo_wine
2550 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2552 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, &mode);
2553 todo_wine
2554 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2555 if (SUCCEEDED(hr))
2556 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2558 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, NULL);
2559 todo_wine
2560 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2562 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, &level);
2563 todo_wine
2564 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2565 if (SUCCEEDED(hr))
2566 ok(level == MF_QUALITY_NORMAL, "Unexpected level %d.\n", level);
2568 IMFQualityAdviseLimits_Release(qa_limits);
2570 todo_wine {
2571 mode = 1;
2572 hr = IMFQualityAdvise_GetDropMode(advise, &mode);
2573 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2574 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2576 level = 1;
2577 hr = IMFQualityAdvise_GetQualityLevel(advise, &level);
2578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2579 ok(level == MF_QUALITY_NORMAL, "Unexpected mode %d.\n", level);
2581 hr = IMFQualityAdvise_SetDropMode(advise, MF_DROP_MODE_1);
2582 ok(hr == MF_E_NO_MORE_DROP_MODES, "Unexpected hr %#lx.\n", hr);
2584 hr = IMFQualityAdvise_SetQualityLevel(advise, MF_QUALITY_NORMAL_MINUS_1);
2585 ok(hr == MF_E_NO_MORE_QUALITY_LEVELS, "Unexpected hr %#lx.\n", hr);
2588 IMFQualityAdvise_Release(advise);
2590 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IQualProp, (void **)&qual_prop);
2591 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2593 hr = IQualProp_get_FramesDrawn(qual_prop, NULL);
2594 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
2596 hr = IQualProp_get_FramesDrawn(qual_prop, &frame_count);
2597 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
2599 IQualProp_Release(qual_prop);
2601 IMFVideoPresenter_Release(presenter);
2604 static void get_output_aperture(IMFTransform *mixer, SIZE *frame_size, MFVideoArea *aperture)
2606 IMFMediaType *media_type;
2607 UINT64 size;
2608 HRESULT hr;
2610 memset(frame_size, 0xcc, sizeof(*frame_size));
2611 memset(aperture, 0xcc, sizeof(*aperture));
2613 hr = IMFTransform_GetOutputCurrentType(mixer, 0, &media_type);
2614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2616 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &size);
2617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2619 frame_size->cx = size >> 32;
2620 frame_size->cy = size;
2622 hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)aperture, sizeof(*aperture), NULL);
2623 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2625 IMFMediaType_Release(media_type);
2628 static void test_presenter_media_type(void)
2630 IMFTopologyServiceLookupClient *lookup_client;
2631 IMFVideoPresenter *presenter;
2632 struct test_host host;
2633 IMFMediaType *input_type;
2634 IDirect3DDeviceManager9 *manager;
2635 HRESULT hr;
2636 IMFTransform *mixer;
2637 IDirect3DDevice9 *device;
2638 unsigned int token;
2639 SIZE frame_size;
2640 HWND window;
2641 MFVideoArea aperture;
2642 IMFVideoDisplayControl *display_control;
2643 RECT dst;
2645 window = create_window();
2646 if (!(device = create_device(window)))
2648 skip("Failed to create a D3D device, skipping tests.\n");
2649 goto done;
2652 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2653 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2655 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2656 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2658 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2659 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2661 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2662 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2664 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2665 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
2667 input_type = create_video_type(&MFVideoFormat_RGB32);
2669 hr = IMFMediaType_SetUINT64(input_type, &MF_MT_FRAME_SIZE, (UINT64)100 << 32 | 50);
2670 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2671 hr = IMFMediaType_SetUINT32(input_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2672 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2674 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2675 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2677 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2680 init_test_host(&host, mixer, presenter);
2682 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
2683 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2684 IMFTopologyServiceLookupClient_Release(lookup_client);
2686 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2687 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2689 /* Set destination rectangle before mixer types are configured. */
2690 SetRect(&dst, 0, 0, 101, 51);
2691 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
2692 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2694 hr = IMFTransform_SetInputType(mixer, 0, input_type, 0);
2695 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2696 IMFMediaType_Release(input_type);
2698 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2701 get_output_aperture(mixer, &frame_size, &aperture);
2702 ok(frame_size.cx == 101 && frame_size.cy == 51, "Unexpected frame size %lu x %lu.\n", frame_size.cx, frame_size.cy);
2703 ok(aperture.Area.cx == 101 && aperture.Area.cy == 51, "Unexpected size %lu x %lu.\n", aperture.Area.cx, aperture.Area.cy);
2704 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2705 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2707 SetRect(&dst, 1, 2, 200, 300);
2708 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
2709 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2711 get_output_aperture(mixer, &frame_size, &aperture);
2712 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %lu x %lu.\n", frame_size.cx, frame_size.cy);
2713 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %lu x %lu.\n", aperture.Area.cx, aperture.Area.cy);
2714 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2715 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2717 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
2718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2720 get_output_aperture(mixer, &frame_size, &aperture);
2721 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %lu x %lu.\n", frame_size.cx, frame_size.cy);
2722 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %lu x %lu.\n", aperture.Area.cx, aperture.Area.cy);
2723 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2724 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2726 IMFVideoDisplayControl_Release(display_control);
2727 IMFVideoPresenter_Release(presenter);
2728 IMFTransform_Release(mixer);
2729 IDirect3DDeviceManager9_Release(manager);
2730 IDirect3DDevice9_Release(device);
2732 done:
2733 DestroyWindow(window);
2736 static void test_presenter_shutdown(void)
2738 IMFTopologyServiceLookupClient *lookup_client;
2739 IMFVideoDisplayControl *display_control;
2740 IMFVideoMediaType *media_type;
2741 IMFVideoPresenter *presenter;
2742 IMFVideoDeviceID *deviceid;
2743 HWND window, window2;
2744 IQualProp *qual_prop;
2745 int frame_count;
2746 HRESULT hr;
2747 DWORD mode;
2748 RECT rect;
2749 SIZE size;
2750 IID iid;
2752 window = create_window();
2753 ok(!!window, "Failed to create test window.\n");
2755 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2756 ok(hr == S_OK, "Failed to create default presenter, hr %#lx.\n", hr);
2758 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2759 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2761 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
2762 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2764 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2765 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2767 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IQualProp, (void **)&qual_prop);
2768 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2770 hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client);
2771 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2773 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2774 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2776 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_BEGINSTREAMING, 0);
2777 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2779 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0);
2780 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2782 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_PROCESSINPUTNOTIFY, 0);
2783 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2785 hr = IMFVideoPresenter_GetCurrentMediaType(presenter, &media_type);
2786 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2788 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
2789 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2791 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &size);
2792 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2794 hr = IMFVideoDisplayControl_GetIdealVideoSize(display_control, &size, &size);
2795 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2797 SetRect(&rect, 0, 0, 10, 10);
2798 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &rect);
2799 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2801 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &rect);
2802 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2804 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
2805 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2807 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2808 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2810 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2811 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2813 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &rect);
2814 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2816 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window2);
2817 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2819 hr = IMFVideoDisplayControl_RepaintVideo(display_control);
2820 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2822 hr = IQualProp_get_FramesDrawn(qual_prop, NULL);
2823 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
2825 hr = IQualProp_get_FramesDrawn(qual_prop, &frame_count);
2826 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
2828 hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client);
2829 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2831 IQualProp_Release(qual_prop);
2832 IMFVideoDeviceID_Release(deviceid);
2833 IMFVideoDisplayControl_Release(display_control);
2834 IMFTopologyServiceLookupClient_Release(lookup_client);
2836 IMFVideoPresenter_Release(presenter);
2838 DestroyWindow(window);
2841 static void test_mixer_output_rectangle(void)
2843 IMFVideoMixerControl *mixer_control;
2844 MFVideoNormalizedRect rect;
2845 IMFTransform *mixer;
2846 HRESULT hr;
2848 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2849 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
2851 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2852 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2854 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, NULL);
2855 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2857 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
2858 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, &rect);
2859 ok(hr == S_OK, "Failed to get output rect, hr %#lx.\n", hr);
2860 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
2861 "Unexpected rectangle.\n");
2863 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, &rect);
2864 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
2866 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, NULL);
2867 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2869 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, &rect);
2870 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
2872 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, NULL);
2873 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2875 /* Wrong bounds. */
2876 set_rect(&rect, 0.0f, 0.0f, 1.1f, 1.0f);
2877 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2878 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2880 set_rect(&rect, -0.1f, 0.0f, 0.5f, 1.0f);
2881 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2882 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2884 /* Flipped. */
2885 set_rect(&rect, 1.0f, 0.0f, 0.0f, 1.0f);
2886 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2887 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2889 set_rect(&rect, 0.0f, 1.0f, 1.0f, 0.5f);
2890 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2891 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2893 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, NULL);
2894 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2896 IMFVideoMixerControl_Release(mixer_control);
2897 IMFTransform_Release(mixer);
2900 static void test_mixer_zorder(void)
2902 IMFVideoMixerControl *mixer_control;
2903 IMFTransform *mixer;
2904 DWORD ids[2];
2905 DWORD value;
2906 HRESULT hr;
2908 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2909 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
2911 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2912 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2914 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, NULL);
2915 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2917 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, NULL);
2918 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2920 value = 1;
2921 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, &value);
2922 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2923 ok(!value, "Unexpected value %lu.\n", value);
2925 value = 1;
2926 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2927 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
2929 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 1);
2930 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2932 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 1);
2933 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2935 /* Exceeds maximum stream number. */
2936 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 20);
2937 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2939 value = 1;
2940 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2941 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2943 value = 0;
2944 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2946 ok(value == 1, "Unexpected zorder %lu.\n", value);
2948 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 0);
2949 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
2951 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 2);
2952 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2954 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 0);
2955 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2957 value = 2;
2958 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2959 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2961 value = 0;
2962 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2964 ok(value == 2, "Unexpected zorder %lu.\n", value);
2966 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 2, 1);
2967 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2969 value = 3;
2970 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2971 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2973 value = 0;
2974 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 3, &value);
2975 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2976 ok(value == 3, "Unexpected zorder %lu.\n", value);
2978 hr = IMFTransform_DeleteInputStream(mixer, 1);
2979 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2980 hr = IMFTransform_DeleteInputStream(mixer, 2);
2981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2982 hr = IMFTransform_DeleteInputStream(mixer, 3);
2983 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2985 ids[0] = 2;
2986 ids[1] = 1;
2987 hr = IMFTransform_AddInputStreams(mixer, 2, ids);
2988 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2990 value = 0;
2991 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2992 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2993 ok(value == 2, "Unexpected zorder %lu.\n", value);
2995 value = 0;
2996 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2997 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2998 ok(value == 1, "Unexpected zorder %lu.\n", value);
3000 IMFVideoMixerControl_Release(mixer_control);
3001 IMFTransform_Release(mixer);
3004 static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, UINT fourcc,
3005 unsigned int width, unsigned int height)
3007 IDirectXVideoAccelerationService *service;
3008 IDirect3DSurface9 *surface = NULL;
3009 IDirect3DDevice9 *device;
3010 HANDLE handle;
3011 HRESULT hr;
3013 hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle);
3014 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3016 hr = IDirect3DDeviceManager9_LockDevice(manager, handle, &device, TRUE);
3017 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3019 hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
3020 (void **)&service);
3021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3023 hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, fourcc,
3024 D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &surface, NULL);
3025 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3027 IDirectXVideoAccelerationService_Release(service);
3029 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00));
3030 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3032 IDirect3DDevice9_Release(device);
3034 hr = IDirect3DDeviceManager9_UnlockDevice(manager, handle, FALSE);
3035 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3037 hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
3038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3040 return surface;
3043 /* Format is assumed as 32bpp */
3044 static DWORD get_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
3046 D3DLOCKED_RECT locked_rect = { 0 };
3047 D3DSURFACE_DESC desc;
3048 DWORD *row, color;
3049 HRESULT hr;
3051 hr = IDirect3DSurface9_GetDesc(surface, &desc);
3052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3053 ok(x < desc.Width && y < desc.Height, "Invalid coordinate.\n");
3054 if (x >= desc.Width || y >= desc.Height) return 0;
3056 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
3057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3059 row = (DWORD *)((char *)locked_rect.pBits + y * locked_rect.Pitch);
3060 color = row[x];
3062 hr = IDirect3DSurface9_UnlockRect(surface);
3063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3065 return color;
3068 static void test_mixer_samples(void)
3070 IDirect3DDeviceManager9 *manager;
3071 MFT_OUTPUT_DATA_BUFFER buffers[2];
3072 IMFVideoProcessor *processor;
3073 IDirect3DSurface9 *surface;
3074 IMFDesiredSample *desired;
3075 IDirect3DDevice9 *device;
3076 IMFMediaType *video_type;
3077 DWORD flags, color, status;
3078 IMFTransform *mixer;
3079 IMFSample *sample, *sample2;
3080 HWND window;
3081 UINT token;
3082 HRESULT hr;
3083 LONGLONG pts, duration;
3084 UINT32 count;
3086 window = create_window();
3087 if (!(device = create_device(window)))
3089 skip("Failed to create a D3D device, skipping tests.\n");
3090 goto done;
3093 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
3094 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
3096 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoProcessor, (void **)&processor);
3097 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3099 hr = IMFTransform_GetInputStatus(mixer, 0, NULL);
3100 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3102 hr = IMFTransform_GetInputStatus(mixer, 1, NULL);
3103 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3105 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
3106 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
3108 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
3109 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
3111 hr = IMFTransform_GetOutputStatus(mixer, NULL);
3112 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3114 hr = IMFTransform_GetOutputStatus(mixer, &status);
3115 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
3117 /* Configure device and media types. */
3118 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
3119 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3121 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
3122 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
3124 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
3125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3127 video_type = create_video_type(&MFVideoFormat_RGB32);
3129 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
3130 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3131 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
3132 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3134 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
3135 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3137 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
3138 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#lx.\n", hr);
3140 hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0);
3141 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3143 status = 0;
3144 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
3145 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3146 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#lx.\n", status);
3148 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
3149 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
3151 status = ~0u;
3152 hr = IMFTransform_GetOutputStatus(mixer, &status);
3153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3154 ok(!status, "Unexpected status %#lx.\n", status);
3156 IMFMediaType_Release(video_type);
3158 memset(buffers, 0, sizeof(buffers));
3159 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3160 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3162 /* It needs a sample with a backing surface. */
3163 hr = MFCreateSample(&sample);
3164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3166 buffers[0].pSample = sample;
3167 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3168 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3170 IMFSample_Release(sample);
3172 surface = create_surface(manager, D3DFMT_A8R8G8B8, 64, 64);
3174 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
3175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3177 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired);
3178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3180 buffers[0].pSample = sample;
3181 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3182 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#lx.\n", hr);
3184 color = get_surface_color(surface, 0, 0);
3185 ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#lx.\n", color);
3187 /* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
3188 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
3190 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3191 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3193 color = get_surface_color(surface, 0, 0);
3194 ok(!color, "Unexpected color %#lx.\n", color);
3196 hr = IMFVideoProcessor_SetBackgroundColor(processor, RGB(0, 0, 255));
3197 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3199 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3200 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3202 color = get_surface_color(surface, 0, 0);
3203 ok(!color, "Unexpected color %#lx.\n", color);
3205 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
3206 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3208 buffers[1].pSample = sample;
3209 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
3210 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3212 buffers[0].dwStreamID = 1;
3213 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3214 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
3216 IMFDesiredSample_Clear(desired);
3217 IMFDesiredSample_Release(desired);
3219 hr = IMFTransform_ProcessInput(mixer, 0, NULL, 0);
3220 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3222 hr = IMFTransform_ProcessInput(mixer, 5, NULL, 0);
3223 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3225 status = 0;
3226 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
3227 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3228 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#lx.\n", status);
3230 status = ~0u;
3231 hr = IMFTransform_GetOutputStatus(mixer, &status);
3232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3233 ok(!status, "Unexpected status %#lx.\n", status);
3235 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
3236 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3238 status = ~0u;
3239 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
3240 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3241 ok(!status, "Unexpected status %#lx.\n", status);
3243 hr = IMFTransform_GetOutputStatus(mixer, &status);
3244 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3245 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#lx.\n", status);
3247 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
3248 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#lx.\n", hr);
3250 hr = IMFTransform_ProcessInput(mixer, 5, sample, 0);
3251 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#lx.\n", hr);
3253 /* ProcessOutput() sets sample time and duration. */
3254 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample2);
3255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3257 hr = IMFSample_SetUINT32(sample2, &IID_IMFSample, 1);
3258 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3260 hr = IMFSample_SetSampleFlags(sample2, 0x123);
3261 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3263 hr = IMFSample_GetSampleTime(sample2, &pts);
3264 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
3266 hr = IMFSample_GetSampleDuration(sample2, &duration);
3267 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
3269 hr = IMFSample_SetSampleTime(sample, 0);
3270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3272 hr = IMFSample_SetSampleDuration(sample, 0);
3273 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3275 memset(buffers, 0, sizeof(buffers));
3276 buffers[0].pSample = sample2;
3277 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
3278 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3280 hr = IMFSample_GetSampleTime(sample2, &pts);
3281 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3282 ok(!pts, "Unexpected sample time.\n");
3284 hr = IMFSample_GetSampleDuration(sample2, &duration);
3285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3286 ok(!duration, "Unexpected duration\n");
3288 /* Flags are not copied. */
3289 hr = IMFSample_GetSampleFlags(sample2, &flags);
3290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3291 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
3293 /* Attributes are not removed. */
3294 hr = IMFSample_GetCount(sample2, &count);
3295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3296 ok(count == 1, "Unexpected attribute count %u.\n", count);
3298 hr = IMFSample_GetCount(sample, &count);
3299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3300 ok(!count, "Unexpected attribute count %u.\n", count);
3302 IMFSample_Release(sample2);
3304 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_DRAIN, 0);
3305 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3307 IMFSample_Release(sample);
3309 IDirect3DSurface9_Release(surface);
3311 IMFVideoProcessor_Release(processor);
3312 IMFTransform_Release(mixer);
3314 IDirect3DDeviceManager9_Release(manager);
3315 ok(!IDirect3DDevice9_Release(device), "Unexpected refcount.\n");
3317 done:
3318 DestroyWindow(window);
3321 static void test_presenter_orientation(const GUID *subtype)
3323 IMFTopologyServiceLookupClient *lookup_client;
3324 static const BITMAPINFOHEADER expect_header =
3326 .biSize = sizeof(BITMAPINFOHEADER),
3327 .biWidth = 96, .biHeight = 96,
3328 .biPlanes = 1, .biBitCount = 32,
3329 .biCompression = BI_RGB,
3330 .biSizeImage = 96 * 96 * 4,
3332 BITMAPINFOHEADER header = {.biSize = sizeof(BITMAPINFOHEADER)};
3333 IMFVideoDisplayControl *display_control;
3334 DWORD diff, data_size, frame_data_len;
3335 IDirect3DDeviceManager9 *manager;
3336 D3DLOCKED_RECT d3d_rect = {0};
3337 IMFVideoPresenter *presenter;
3338 IDirect3DSurface9 *surface;
3339 IMFMediaType *video_type;
3340 const BYTE *frame_data;
3341 struct test_host host;
3342 IMFTransform *mixer;
3343 LONGLONG timestamp;
3344 IMFSample *sample;
3345 LONG stride;
3346 HWND window;
3347 BYTE *data;
3348 HRESULT hr;
3349 RECT rect;
3351 window = create_window();
3353 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
3354 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
3355 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
3356 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3358 init_test_host(&host, mixer, presenter);
3359 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
3360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3361 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
3362 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3363 IMFTopologyServiceLookupClient_Release(lookup_client);
3365 /* Configure device and media types. */
3367 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&manager);
3368 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3369 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
3370 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3371 IDirect3DDeviceManager9_Release(manager);
3373 video_type = create_video_type(subtype);
3374 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)expect_header.biWidth << 32 | expect_header.biHeight);
3375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3376 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
3377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3379 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
3380 if (broken(IsEqualGUID(subtype, &MFVideoFormat_NV12) && hr == E_FAIL))
3382 win_skip("Skipping unsupported NV12 format\n");
3383 IMFMediaType_Release(video_type);
3384 goto skip_tests;
3386 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3387 hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0);
3388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3389 IMFMediaType_Release(video_type);
3391 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
3392 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3393 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_BEGINSTREAMING, 0);
3394 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3396 if (IsEqualGUID(subtype, &MFVideoFormat_NV12))
3398 load_resource(L"nv12frame.bmp", &frame_data, &frame_data_len);
3399 /* skip BMP header and RGB data from the dump */
3400 data_size = *(DWORD *)(frame_data + 2);
3401 frame_data_len = frame_data_len - data_size;
3402 frame_data = frame_data + data_size;
3403 ok(frame_data_len == 13824, "got length %lu\n", frame_data_len);
3405 else
3407 load_resource(L"rgb32frame.bmp", &frame_data, &frame_data_len);
3408 /* skip BMP header from the dump */
3409 data_size = *(DWORD *)(frame_data + 2 + 2 * sizeof(DWORD));
3410 frame_data_len -= data_size;
3411 frame_data += data_size;
3412 ok(frame_data_len == 36864, "got length %lu\n", frame_data_len);
3415 surface = create_surface(manager, subtype->Data1, expect_header.biWidth, expect_header.biHeight);
3416 ok(!!surface, "Failed to create input surface.\n");
3417 hr = IDirect3DSurface9_LockRect(surface, &d3d_rect, NULL, 0);
3418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3419 if (IsEqualGUID(subtype, &MFVideoFormat_RGB32))
3420 memcpy(d3d_rect.pBits, frame_data, frame_data_len);
3421 else if (IsEqualGUID(subtype, &MFVideoFormat_NV12))
3423 hr = MFGetStrideForBitmapInfoHeader(subtype->Data1, expect_header.biWidth, &stride);
3424 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3425 hr = MFCopyImage(d3d_rect.pBits, d3d_rect.Pitch, frame_data, stride, expect_header.biWidth, expect_header.biHeight);
3426 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3427 frame_data += stride * expect_header.biHeight;
3428 d3d_rect.pBits = (BYTE *)d3d_rect.pBits + d3d_rect.Pitch * expect_header.biHeight;
3429 hr = MFCopyImage(d3d_rect.pBits, d3d_rect.Pitch, frame_data, stride, expect_header.biWidth, expect_header.biHeight / 2);
3430 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3432 hr = IDirect3DSurface9_UnlockRect(surface);
3433 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3434 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
3435 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3436 IDirect3DSurface9_Release(surface);
3438 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
3439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3440 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_PROCESSINPUTNOTIFY, 0);
3441 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3442 IMFSample_Release(sample);
3444 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
3445 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3446 hr = IMFVideoDisplayControl_GetCurrentImage(display_control, &header, &data, &data_size, &timestamp);
3447 if (hr == MF_E_INVALIDREQUEST)
3449 Sleep(500);
3450 hr = IMFVideoDisplayControl_GetCurrentImage(display_control, &header, &data, &data_size, &timestamp);
3452 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3453 IMFVideoDisplayControl_Release(display_control);
3455 ok(header.biSize == expect_header.biSize, "Unexpected biSize %#lx\n", header.biSize);
3456 ok(header.biWidth == expect_header.biWidth, "Unexpected biWidth %#lx\n", header.biWidth);
3457 ok(header.biHeight == expect_header.biHeight, "Unexpected biHeight %#lx\n", header.biHeight);
3458 ok(header.biPlanes == expect_header.biPlanes, "Unexpected biPlanes %#x\n", header.biPlanes);
3459 ok(header.biBitCount == expect_header.biBitCount, "Unexpected biBitCount %#x\n", header.biBitCount);
3460 ok(header.biCompression == expect_header.biCompression, "Unexpected biCompression %#lx\n", header.biCompression);
3461 ok(header.biSizeImage == expect_header.biSizeImage, "Unexpected biSizeImage %#lx\n", header.biSizeImage);
3462 ok(header.biXPelsPerMeter == expect_header.biXPelsPerMeter, "Unexpected biXPelsPerMeter %#lx\n", header.biXPelsPerMeter);
3463 ok(header.biYPelsPerMeter == expect_header.biYPelsPerMeter, "Unexpected biYPelsPerMeter %#lx\n", header.biYPelsPerMeter);
3464 ok(header.biClrUsed == expect_header.biClrUsed, "Unexpected biClrUsed %#lx\n", header.biClrUsed);
3465 ok(header.biClrImportant == expect_header.biClrImportant, "Unexpected biClrImportant %#lx\n", header.biClrImportant);
3467 SetRect(&rect, 0, 0, header.biWidth, header.biHeight);
3468 diff = check_rgb32_data(L"rgb32frame-flip.bmp", data, header.biSizeImage, &rect);
3469 ok(diff <= 5, "Unexpected %lu%% diff\n", diff);
3470 CoTaskMemFree(data);
3472 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0);
3473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3475 skip_tests:
3476 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
3477 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3478 hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client);
3479 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3480 IMFTopologyServiceLookupClient_Release(lookup_client);
3482 IMFTransform_Release(mixer);
3483 IMFVideoPresenter_Release(presenter);
3485 DestroyWindow(window);
3488 static void test_MFIsFormatYUV(void)
3490 static const DWORD formats[] =
3492 D3DFMT_UYVY,
3493 D3DFMT_YUY2,
3494 MAKEFOURCC('A','Y','U','V'),
3495 MAKEFOURCC('I','M','C','1'),
3496 MAKEFOURCC('I','M','C','2'),
3497 MAKEFOURCC('Y','V','1','2'),
3498 MAKEFOURCC('N','V','1','1'),
3499 MAKEFOURCC('N','V','1','2'),
3500 MAKEFOURCC('Y','2','1','0'),
3501 MAKEFOURCC('Y','2','1','6'),
3503 static const DWORD unsupported_formats[] =
3505 D3DFMT_A8R8G8B8,
3506 MAKEFOURCC('I','Y','U','V'),
3507 MAKEFOURCC('I','4','2','0'),
3508 MAKEFOURCC('Y','V','Y','U'),
3509 MAKEFOURCC('Y','V','U','9'),
3510 MAKEFOURCC('Y','4','1','0'),
3511 MAKEFOURCC('Y','4','1','6'),
3513 unsigned int i;
3514 BOOL ret;
3516 for (i = 0; i < ARRAY_SIZE(formats); ++i)
3518 ret = MFIsFormatYUV(formats[i]);
3519 ok(ret, "Unexpected ret %d, format %s.\n", ret, debugstr_an((char *)&formats[i], 4));
3522 for (i = 0; i < ARRAY_SIZE(unsupported_formats); ++i)
3524 ret = MFIsFormatYUV(unsupported_formats[i]);
3525 ok(!ret, "Unexpected ret %d, format %s.\n", ret, debugstr_an((char *)&unsupported_formats[i], 4));
3529 static void test_mixer_render(void)
3531 IMFMediaType *video_type, *output_type;
3532 IMFVideoMixerControl *mixer_control;
3533 IDirect3DDeviceManager9 *manager;
3534 IMFVideoProcessor *processor;
3535 IDirect3DSurface9 *surface;
3536 IDirect3DDevice9 *device;
3537 IMFTransform *mixer;
3538 IMFSample *sample;
3539 DWORD status;
3540 HWND window;
3541 UINT token;
3542 HRESULT hr;
3544 window = create_window();
3545 if (!(device = create_device(window)))
3547 skip("Failed to create a D3D device, skipping tests.\n");
3548 goto done;
3551 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
3552 ok(hr == S_OK, "Failed to create a mixer, hr %#lx.\n", hr);
3554 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoProcessor, (void **)&processor);
3555 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3556 IMFVideoProcessor_Release(processor);
3558 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
3559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3560 IMFVideoMixerControl_Release(mixer_control);
3562 /* Configure device and media types. */
3563 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
3564 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3566 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
3567 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
3569 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
3570 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3572 video_type = create_video_type(&MFVideoFormat_RGB32);
3574 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)64 << 32 | 64);
3575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3576 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
3577 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3579 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
3580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3582 hr = IMFTransform_GetOutputAvailableType(mixer, 0, 0, &output_type);
3583 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3585 hr = IMFTransform_SetOutputType(mixer, 0, output_type, 0);
3586 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3588 IMFMediaType_Release(output_type);
3589 IMFMediaType_Release(video_type);
3591 surface = create_surface(manager, D3DFMT_A8R8G8B8, 64, 64);
3592 ok(!!surface, "Failed to create input surface.\n");
3594 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
3595 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3597 EXPECT_REF(sample, 1);
3598 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
3599 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3600 EXPECT_REF(sample, 2);
3602 hr = IMFTransform_GetOutputStatus(mixer, &status);
3603 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3604 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#lx.\n", status);
3606 /* FLUSH/END_STREAMING releases input */
3607 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_NOTIFY_END_STREAMING, 0);
3608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3609 EXPECT_REF(sample, 1);
3611 hr = IMFTransform_GetOutputStatus(mixer, &status);
3612 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3613 ok(!status, "Unexpected status %#lx.\n", status);
3615 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
3616 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3617 EXPECT_REF(sample, 2);
3619 hr = IMFTransform_GetOutputStatus(mixer, &status);
3620 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3621 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#lx.\n", status);
3623 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_FLUSH, 0);
3624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3625 EXPECT_REF(sample, 1);
3627 hr = IMFTransform_GetOutputStatus(mixer, &status);
3628 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3629 ok(!status, "Unexpected status %#lx.\n", status);
3631 IMFSample_Release(sample);
3632 IDirect3DSurface9_Release(surface);
3633 IMFTransform_Release(mixer);
3635 IDirect3DDeviceManager9_Release(manager);
3636 ok(!IDirect3DDevice9_Release(device), "Unexpected refcount.\n");
3638 done:
3639 DestroyWindow(window);
3642 START_TEST(evr)
3644 IMFVideoPresenter *presenter;
3645 IDirect3D9 *d3d9;
3646 HRESULT hr;
3648 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
3649 if (!d3d9)
3651 skip("Failed to initialize D3D9. Skipping EVR tests.\n");
3652 return;
3654 IDirect3D9_Release(d3d9);
3656 CoInitialize(NULL);
3658 if (FAILED(hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter)))
3660 win_skip("Failed to create default presenter, hr %#lx. Skipping tests.\n", hr);
3661 CoUninitialize();
3662 return;
3664 IMFVideoPresenter_Release(presenter);
3666 test_aggregation();
3667 test_interfaces();
3668 test_enum_pins();
3669 test_find_pin();
3670 test_pin_info();
3671 test_unconnected_eos();
3672 test_misc_flags();
3673 test_display_control();
3674 test_service_lookup();
3675 test_query_accept();
3677 test_default_mixer();
3678 test_default_mixer_type_negotiation();
3679 test_surface_sample();
3680 test_default_presenter();
3681 test_MFCreateVideoMixerAndPresenter();
3682 test_MFCreateVideoSampleAllocator();
3683 test_presenter_video_position();
3684 test_presenter_native_video_size();
3685 test_presenter_ar_mode();
3686 test_presenter_video_window();
3687 test_presenter_quality_control();
3688 test_presenter_media_type();
3689 test_presenter_orientation(&MFVideoFormat_NV12);
3690 test_presenter_orientation(&MFVideoFormat_RGB32);
3691 test_presenter_shutdown();
3692 test_mixer_output_rectangle();
3693 test_mixer_zorder();
3694 test_mixer_samples();
3695 test_mixer_render();
3696 test_MFIsFormatYUV();
3698 CoUninitialize();