evr/presenter: Add IMFQualityAdviseLimits stub.
[wine.git] / dlls / evr / tests / evr.c
blobfb4a2130f37cd4ef4d65c27671e5fbf28fdb7c85
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 set_rect(MFVideoNormalizedRect *rect, float left, float top, float right, float bottom)
36 rect->left = left;
37 rect->top = top;
38 rect->right = right;
39 rect->bottom = bottom;
42 static HWND create_window(void)
44 RECT r = {0, 0, 640, 480};
46 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
48 return CreateWindowA("static", "evr_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
49 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
52 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
54 D3DPRESENT_PARAMETERS present_parameters = {0};
55 IDirect3DDevice9 *device = NULL;
57 present_parameters.BackBufferWidth = 640;
58 present_parameters.BackBufferHeight = 480;
59 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
60 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
61 present_parameters.hDeviceWindow = focus_window;
62 present_parameters.Windowed = TRUE;
63 present_parameters.EnableAutoDepthStencil = TRUE;
64 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
66 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
67 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
69 return device;
72 static IBaseFilter *create_evr(void)
74 IBaseFilter *filter = NULL;
75 HRESULT hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC_SERVER,
76 &IID_IBaseFilter, (void **)&filter);
77 ok(hr == S_OK, "Got hr %#x.\n", hr);
78 return filter;
81 static ULONG get_refcount(void *iface)
83 IUnknown *unknown = iface;
84 IUnknown_AddRef(unknown);
85 return IUnknown_Release(unknown);
88 static const GUID test_iid = {0x33333333};
89 static LONG outer_ref = 1;
91 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
93 if (IsEqualGUID(iid, &IID_IUnknown)
94 || IsEqualGUID(iid, &IID_IBaseFilter)
95 || IsEqualGUID(iid, &test_iid))
97 *out = (IUnknown *)0xdeadbeef;
98 return S_OK;
100 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
101 return E_NOINTERFACE;
104 static ULONG WINAPI outer_AddRef(IUnknown *iface)
106 return InterlockedIncrement(&outer_ref);
109 static ULONG WINAPI outer_Release(IUnknown *iface)
111 return InterlockedDecrement(&outer_ref);
114 static const IUnknownVtbl outer_vtbl =
116 outer_QueryInterface,
117 outer_AddRef,
118 outer_Release,
121 static IUnknown test_outer = {&outer_vtbl};
123 static void test_aggregation(void)
125 IBaseFilter *filter, *filter2;
126 IMFVideoPresenter *presenter;
127 IUnknown *unk, *unk2;
128 IMFTransform *mixer;
129 HRESULT hr;
130 ULONG ref;
132 filter = (IBaseFilter *)0xdeadbeef;
133 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
134 &IID_IBaseFilter, (void **)&filter);
135 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
136 ok(!filter, "Got interface %p.\n", filter);
138 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
139 &IID_IUnknown, (void **)&unk);
140 ok(hr == S_OK, "Got hr %#x.\n", hr);
141 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
142 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
143 ref = get_refcount(unk);
144 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
146 ref = IUnknown_AddRef(unk);
147 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
148 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
150 ref = IUnknown_Release(unk);
151 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
152 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
154 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
155 ok(hr == S_OK, "Got hr %#x.\n", hr);
156 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
157 IUnknown_Release(unk2);
159 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
160 ok(hr == S_OK, "Got hr %#x.\n", hr);
162 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
163 ok(hr == S_OK, "Got hr %#x.\n", hr);
164 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
166 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
167 ok(hr == S_OK, "Got hr %#x.\n", hr);
168 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
170 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
171 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
172 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
174 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
175 ok(hr == S_OK, "Got hr %#x.\n", hr);
176 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
178 IBaseFilter_Release(filter);
179 ref = IUnknown_Release(unk);
180 ok(!ref, "Got unexpected refcount %d.\n", ref);
181 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
183 /* Default presenter. */
184 presenter = (void *)0xdeadbeef;
185 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter,
186 (void **)&presenter);
187 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
188 ok(!presenter, "Got interface %p.\n", presenter);
190 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
191 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Unexpected hr %#x.\n", hr);
192 if (SUCCEEDED(hr))
194 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
195 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
196 ref = get_refcount(unk);
197 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
199 IUnknown_Release(unk);
202 /* Default mixer. */
203 presenter = (void *)0xdeadbeef;
204 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
205 (void **)&mixer);
206 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
207 ok(!mixer, "Got interface %p.\n", mixer);
209 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
210 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
211 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
212 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
213 ref = get_refcount(unk);
214 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
216 IUnknown_Release(unk);
219 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
220 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
222 IUnknown *iface = iface_ptr;
223 HRESULT hr, expected_hr;
224 IUnknown *unk;
226 expected_hr = supported ? S_OK : E_NOINTERFACE;
228 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
229 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
230 if (SUCCEEDED(hr))
231 IUnknown_Release(unk);
234 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
235 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
237 IUnknown *iface = iface_ptr;
238 HRESULT hr, expected_hr;
239 IUnknown *unk;
241 expected_hr = supported ? S_OK : E_NOINTERFACE;
243 hr = MFGetService(iface, service, iid, (void **)&unk);
244 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
245 if (SUCCEEDED(hr))
246 IUnknown_Release(unk);
249 static void test_interfaces(void)
251 IBaseFilter *filter = create_evr();
252 ULONG ref;
254 todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
255 check_interface(filter, &IID_IBaseFilter, TRUE);
256 check_interface(filter, &IID_IMediaFilter, TRUE);
257 check_interface(filter, &IID_IMediaPosition, TRUE);
258 check_interface(filter, &IID_IMediaSeeking, TRUE);
259 check_interface(filter, &IID_IPersist, TRUE);
260 check_interface(filter, &IID_IUnknown, TRUE);
262 check_interface(filter, &IID_IBasicAudio, FALSE);
263 check_interface(filter, &IID_IBasicVideo, FALSE);
264 check_interface(filter, &IID_IDirectXVideoMemoryConfiguration, FALSE);
265 check_interface(filter, &IID_IMemInputPin, FALSE);
266 check_interface(filter, &IID_IPersistPropertyBag, FALSE);
267 check_interface(filter, &IID_IPin, FALSE);
268 check_interface(filter, &IID_IReferenceClock, FALSE);
269 check_interface(filter, &IID_IVideoWindow, FALSE);
271 ref = IBaseFilter_Release(filter);
272 ok(!ref, "Got unexpected refcount %d.\n", ref);
275 static void test_enum_pins(void)
277 IBaseFilter *filter = create_evr();
278 IEnumPins *enum1, *enum2;
279 ULONG count, ref;
280 IPin *pins[2];
281 HRESULT hr;
283 ref = get_refcount(filter);
284 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
286 hr = IBaseFilter_EnumPins(filter, NULL);
287 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
289 hr = IBaseFilter_EnumPins(filter, &enum1);
290 ok(hr == S_OK, "Got hr %#x.\n", hr);
291 ref = get_refcount(filter);
292 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
293 ref = get_refcount(enum1);
294 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
296 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
297 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
299 hr = IEnumPins_Next(enum1, 1, pins, NULL);
300 ok(hr == S_OK, "Got hr %#x.\n", hr);
301 ref = get_refcount(filter);
302 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
303 ref = get_refcount(pins[0]);
304 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
305 ref = get_refcount(enum1);
306 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
307 IPin_Release(pins[0]);
308 ref = get_refcount(filter);
309 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
311 hr = IEnumPins_Next(enum1, 1, pins, NULL);
312 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
314 hr = IEnumPins_Reset(enum1);
315 ok(hr == S_OK, "Got hr %#x.\n", hr);
317 hr = IEnumPins_Next(enum1, 1, pins, &count);
318 ok(hr == S_OK, "Got hr %#x.\n", hr);
319 ok(count == 1, "Got count %u.\n", count);
320 IPin_Release(pins[0]);
322 hr = IEnumPins_Next(enum1, 1, pins, &count);
323 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
324 ok(!count, "Got count %u.\n", count);
326 hr = IEnumPins_Reset(enum1);
327 ok(hr == S_OK, "Got hr %#x.\n", hr);
329 hr = IEnumPins_Next(enum1, 2, pins, NULL);
330 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
332 hr = IEnumPins_Next(enum1, 2, pins, &count);
333 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
334 ok(count == 1, "Got count %u.\n", count);
335 IPin_Release(pins[0]);
337 hr = IEnumPins_Reset(enum1);
338 ok(hr == S_OK, "Got hr %#x.\n", hr);
340 hr = IEnumPins_Clone(enum1, &enum2);
341 ok(hr == S_OK, "Got hr %#x.\n", hr);
343 hr = IEnumPins_Skip(enum1, 2);
344 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
346 hr = IEnumPins_Skip(enum1, 1);
347 ok(hr == S_OK, "Got hr %#x.\n", hr);
349 hr = IEnumPins_Skip(enum1, 1);
350 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
352 hr = IEnumPins_Next(enum1, 1, pins, NULL);
353 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
355 hr = IEnumPins_Next(enum2, 1, pins, NULL);
356 ok(hr == S_OK, "Got hr %#x.\n", hr);
357 IPin_Release(pins[0]);
359 IEnumPins_Release(enum2);
360 IEnumPins_Release(enum1);
361 ref = IBaseFilter_Release(filter);
362 ok(!ref, "Got outstanding refcount %d.\n", ref);
365 static void test_find_pin(void)
367 IBaseFilter *filter = create_evr();
368 IEnumPins *enum_pins;
369 IPin *pin, *pin2;
370 HRESULT hr;
371 ULONG ref;
373 hr = IBaseFilter_EnumPins(filter, &enum_pins);
374 ok(hr == S_OK, "Got hr %#x.\n", hr);
376 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
377 ok(hr == S_OK, "Got hr %#x.\n", hr);
378 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
379 ok(hr == S_OK, "Got hr %#x.\n", hr);
380 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
381 IPin_Release(pin2);
382 IPin_Release(pin);
384 IEnumPins_Release(enum_pins);
385 ref = IBaseFilter_Release(filter);
386 ok(!ref, "Got outstanding refcount %d.\n", ref);
389 static void test_pin_info(void)
391 IBaseFilter *filter = create_evr();
392 PIN_DIRECTION dir;
393 PIN_INFO info;
394 HRESULT hr;
395 WCHAR *id;
396 ULONG ref;
397 IPin *pin;
399 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
400 ok(hr == S_OK, "Got hr %#x.\n", hr);
401 ref = get_refcount(filter);
402 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
403 ref = get_refcount(pin);
404 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
406 hr = IPin_QueryPinInfo(pin, &info);
407 ok(hr == S_OK, "Got hr %#x.\n", hr);
408 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
409 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
410 ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
411 ref = get_refcount(filter);
412 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
413 ref = get_refcount(pin);
414 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
415 IBaseFilter_Release(info.pFilter);
417 hr = IPin_QueryDirection(pin, &dir);
418 ok(hr == S_OK, "Got hr %#x.\n", hr);
419 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
421 hr = IPin_QueryId(pin, &id);
422 ok(hr == S_OK, "Got hr %#x.\n", hr);
423 ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
424 CoTaskMemFree(id);
426 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
427 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
429 IPin_Release(pin);
430 ref = IBaseFilter_Release(filter);
431 ok(!ref, "Got outstanding refcount %d.\n", ref);
434 static IMFMediaType * create_video_type(const GUID *subtype)
436 IMFMediaType *video_type;
437 HRESULT hr;
439 hr = MFCreateMediaType(&video_type);
440 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
442 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
443 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
445 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
446 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
448 return video_type;
451 static void test_default_mixer(void)
453 DWORD input_min, input_max, output_min, output_max;
454 IMFAttributes *attributes, *attributes2;
455 IMFVideoMixerControl2 *mixer_control2;
456 MFT_OUTPUT_STREAM_INFO output_info;
457 MFT_INPUT_STREAM_INFO input_info;
458 DWORD input_count, output_count;
459 IMFVideoProcessor *processor;
460 IMFVideoDeviceID *deviceid;
461 MFVideoNormalizedRect rect;
462 DWORD input_id, output_id;
463 IMFTransform *transform;
464 DXVA2_ValueRange range;
465 DXVA2_Fixed32 dxva_value;
466 DWORD flags, value, count;
467 COLORREF color;
468 unsigned int i;
469 DWORD ids[16];
470 IUnknown *unk;
471 GUID *guids;
472 HRESULT hr;
473 IID iid;
475 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
476 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
478 check_interface(transform, &IID_IMFQualityAdvise, TRUE);
479 check_interface(transform, &IID_IMFClockStateSink, TRUE);
480 check_interface(transform, &IID_IMFTopologyServiceLookupClient, TRUE);
481 check_interface(transform, &IID_IMFGetService, TRUE);
482 check_interface(transform, &IID_IMFAttributes, TRUE);
483 check_interface(transform, &IID_IMFVideoMixerBitmap, TRUE);
484 check_interface(transform, &IID_IMFVideoPositionMapper, TRUE);
485 check_interface(transform, &IID_IMFVideoProcessor, TRUE);
486 check_interface(transform, &IID_IMFVideoMixerControl, TRUE);
487 check_interface(transform, &IID_IMFVideoDeviceID, TRUE);
488 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerBitmap, TRUE);
489 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, TRUE);
490 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, TRUE);
491 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
492 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFTransform, FALSE);
494 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_RENDER_SERVICE, &IID_IUnknown, (void **)&unk);
495 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#x.\n", hr);
497 if (SUCCEEDED(MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl2, (void **)&mixer_control2)))
499 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, NULL);
500 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
502 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, &flags);
503 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
504 ok(!flags, "Unexpected flags %#x.\n", flags);
506 IMFVideoMixerControl2_Release(mixer_control2);
509 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, (void **)&processor);
510 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
512 hr = IMFVideoProcessor_GetBackgroundColor(processor, NULL);
513 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
515 color = 1;
516 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
517 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
518 ok(!color, "Unexpected color %#x.\n", color);
520 hr = IMFVideoProcessor_SetBackgroundColor(processor, 0x00121212);
521 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
523 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
524 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
525 ok(color == 0x121212, "Unexpected color %#x.\n", color);
527 hr = IMFVideoProcessor_GetFilteringRange(processor, DXVA2_DetailFilterChromaLevel, &range);
528 todo_wine
529 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
531 hr = IMFVideoProcessor_GetFilteringValue(processor, DXVA2_DetailFilterChromaLevel, &dxva_value);
532 todo_wine
533 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
535 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
536 todo_wine
537 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
539 IMFVideoProcessor_Release(processor);
541 hr = IMFTransform_SetOutputBounds(transform, 100, 10);
542 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
544 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid);
545 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
547 hr = IMFTransform_GetAttributes(transform, NULL);
548 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
550 hr = IMFTransform_GetAttributes(transform, &attributes);
551 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
553 hr = IMFTransform_GetAttributes(transform, &attributes2);
554 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
555 ok(attributes == attributes2, "Unexpected attributes instance.\n");
556 IMFAttributes_Release(attributes2);
558 hr = IMFTransform_QueryInterface(transform, &IID_IMFAttributes, (void **)&attributes2);
559 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
560 ok(attributes != attributes2, "Unexpected attributes instance.\n");
562 hr = IMFAttributes_QueryInterface(attributes2, &IID_IMFTransform, (void **)&unk);
563 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
564 IUnknown_Release(unk);
566 hr = IMFAttributes_GetCount(attributes2, &count);
567 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
568 ok(count == 1, "Unexpected attribute count %u.\n", count);
570 value = 0;
571 hr = IMFAttributes_GetUINT32(attributes2, &MF_SA_D3D_AWARE, &value);
572 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
573 ok(value == 1, "Unexpected value %d.\n", value);
575 IMFAttributes_Release(attributes2);
577 hr = IMFAttributes_GetCount(attributes, &count);
578 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
579 ok(count == 1, "Unexpected attribute count %u.\n", count);
581 memset(&rect, 0, sizeof(rect));
582 hr = IMFAttributes_GetBlob(attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&rect, sizeof(rect), NULL);
583 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
584 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
585 "Unexpected zoom rect (%f, %f) - (%f, %f).\n", rect.left, rect.top, rect.right, rect.bottom);
587 IMFAttributes_Release(attributes);
589 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
590 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
592 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
593 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
594 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
596 IMFVideoDeviceID_Release(deviceid);
598 /* Stream configuration. */
599 input_count = output_count = 0;
600 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
601 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
602 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
604 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
605 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
606 ok(input_min == 1 && input_max == 16 && output_min == 1 && output_max == 1, "Unexpected stream limits %u/%u, %u/%u.\n",
607 input_min, input_max, output_min, output_max);
609 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
610 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
612 hr = IMFTransform_GetOutputStreamInfo(transform, 1, &output_info);
613 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
615 memset(&input_info, 0xcc, sizeof(input_info));
616 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
617 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
619 memset(&output_info, 0xcc, sizeof(output_info));
620 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
621 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
622 ok(!(output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)),
623 "Unexpected output flags %#x.\n", output_info.dwFlags);
625 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
626 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
627 ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
629 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
630 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
632 hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
633 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
635 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
636 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
638 hr = IMFTransform_AddInputStreams(transform, 16, NULL);
639 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
641 hr = IMFTransform_AddInputStreams(transform, 16, ids);
642 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
644 memset(ids, 0, sizeof(ids));
645 hr = IMFTransform_AddInputStreams(transform, 15, ids);
646 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
648 for (i = 0; i < ARRAY_SIZE(ids); ++i)
649 ids[i] = i + 1;
651 hr = IMFTransform_AddInputStreams(transform, 15, ids);
652 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
654 input_count = output_count = 0;
655 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
656 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
657 ok(input_count == 16 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
659 memset(&input_info, 0, sizeof(input_info));
660 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
661 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
662 ok((input_info.dwFlags & (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL)) ==
663 (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL), "Unexpected flags %#x.\n", input_info.dwFlags);
665 attributes = NULL;
666 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
667 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
668 hr = IMFAttributes_GetCount(attributes, &count);
669 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
670 ok(count == 1, "Unexpected count %u.\n", count);
671 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &count);
672 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
673 ok(count == 1, "Unexpected count %u.\n", count);
674 ok(!!attributes, "Unexpected attributes.\n");
676 attributes2 = NULL;
677 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
678 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
679 ok(attributes == attributes2, "Unexpected instance.\n");
681 IMFAttributes_Release(attributes2);
682 IMFAttributes_Release(attributes);
684 attributes = NULL;
685 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
686 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
687 ok(!!attributes, "Unexpected attributes.\n");
688 IMFAttributes_Release(attributes);
690 hr = IMFTransform_DeleteInputStream(transform, 0);
691 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
693 hr = IMFTransform_DeleteInputStream(transform, 1);
694 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
696 input_count = output_count = 0;
697 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
698 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
699 ok(input_count == 15 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
701 IMFTransform_Release(transform);
703 hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
704 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
706 hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
707 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
708 IMFTransform_Release(transform);
711 static void test_surface_sample(void)
713 IDirect3DSurface9 *backbuffer = NULL, *surface;
714 IMFDesiredSample *desired_sample;
715 IMFMediaBuffer *buffer, *buffer2;
716 LONGLONG duration, time1, time2;
717 IDirect3DSwapChain9 *swapchain;
718 DWORD flags, count, length;
719 IDirect3DDevice9 *device;
720 IMFSample *sample;
721 IDirect3D9 *d3d;
722 IUnknown *unk;
723 HWND window;
724 HRESULT hr;
725 BYTE *data;
727 window = create_window();
728 d3d = Direct3DCreate9(D3D_SDK_VERSION);
729 ok(!!d3d, "Failed to create a D3D object.\n");
730 if (!(device = create_device(d3d, window)))
732 skip("Failed to create a D3D device, skipping tests.\n");
733 goto done;
736 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
737 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
739 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
740 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
741 ok(backbuffer != NULL, "The back buffer is NULL\n");
743 IDirect3DSwapChain9_Release(swapchain);
745 hr = MFCreateVideoSampleFromSurface(NULL, &sample);
746 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
747 IMFSample_Release(sample);
749 hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample);
750 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
752 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
753 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
754 IUnknown_Release(unk);
756 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired_sample);
757 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
759 hr = IMFSample_GetCount(sample, &count);
760 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
761 ok(!count, "Unexpected attribute count %u.\n", count);
763 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, NULL);
764 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
766 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, &time2);
767 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
769 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, NULL);
770 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
772 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
773 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
775 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 123, 456);
777 time1 = time2 = 0;
778 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
779 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
780 ok(time1 == 123 && time2 == 456, "Unexpected time values.\n");
782 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 0, 0);
784 time1 = time2 = 1;
785 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
786 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
787 ok(time1 == 0 && time2 == 0, "Unexpected time values.\n");
789 IMFDesiredSample_Clear(desired_sample);
791 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
792 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
794 hr = IMFSample_GetCount(sample, &count);
795 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
796 ok(!count, "Unexpected attribute count %u.\n", count);
798 /* Attributes are cleared. */
799 hr = IMFSample_SetUnknown(sample, &MFSampleExtension_Token, NULL);
800 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
802 hr = IMFSample_GetCount(sample, &count);
803 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
804 ok(count == 1, "Unexpected attribute count %u.\n", count);
806 hr = IMFSample_SetSampleTime(sample, 0);
807 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
809 hr = IMFSample_GetSampleTime(sample, &time1);
810 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
812 hr = IMFSample_SetSampleDuration(sample, 0);
813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
815 hr = IMFSample_GetSampleDuration(sample, &duration);
816 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
818 hr = IMFSample_SetSampleFlags(sample, 0x1);
819 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
821 IMFDesiredSample_Clear(desired_sample);
823 hr = IMFSample_GetCount(sample, &count);
824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
825 ok(!count, "Unexpected attribute count %u.\n", count);
827 hr = IMFSample_GetSampleTime(sample, &time1);
828 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
830 hr = IMFSample_GetSampleDuration(sample, &duration);
831 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
833 hr = IMFSample_GetSampleFlags(sample, &flags);
834 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
835 ok(flags == 0, "Unexpected flags %#x.\n", flags);
837 IMFDesiredSample_Release(desired_sample);
839 hr = IMFSample_GetCount(sample, &count);
840 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
841 ok(!count, "Unexpected attribute count.\n");
843 count = 0;
844 hr = IMFSample_GetBufferCount(sample, &count);
845 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
846 ok(count == 1, "Unexpected attribute count.\n");
848 hr = IMFSample_GetTotalLength(sample, &length);
849 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
850 ok(!length, "Unexpected length %u.\n", length);
852 hr = IMFSample_GetSampleDuration(sample, &duration);
853 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
855 hr = IMFSample_GetSampleTime(sample, &duration);
856 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
858 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
859 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
861 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
862 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
864 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
865 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
866 ok(!length, "Unexpected length %u.\n", length);
868 hr = IMFMediaBuffer_SetCurrentLength(buffer, 16);
869 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
871 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
872 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
873 ok(length == 16, "Unexpected length %u.\n", length);
875 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
876 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
878 hr = IMFMediaBuffer_Unlock(buffer);
879 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
881 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk);
882 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
884 hr = IMFSample_AddBuffer(sample, buffer);
885 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
887 hr = IMFSample_GetBufferCount(sample, &count);
888 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
889 ok(count == 2, "Unexpected attribute count.\n");
891 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
892 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
894 hr = IMFSample_CopyToBuffer(sample, buffer);
895 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
897 hr = IMFSample_RemoveAllBuffers(sample);
898 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
900 hr = IMFSample_GetBufferCount(sample, &count);
901 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
902 ok(!count, "Unexpected attribute count.\n");
904 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
906 ok(surface == backbuffer, "Unexpected instance.\n");
907 IDirect3DSurface9_Release(surface);
909 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IUnknown, (void **)&surface);
910 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
911 ok(surface == backbuffer, "Unexpected instance.\n");
912 IDirect3DSurface9_Release(surface);
914 IMFMediaBuffer_Release(buffer);
916 hr = IMFSample_GetSampleFlags(sample, &flags);
917 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
919 hr = IMFSample_SetSampleFlags(sample, 0x123);
920 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
922 flags = 0;
923 hr = IMFSample_GetSampleFlags(sample, &flags);
924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
925 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
927 IMFSample_Release(sample);
929 done:
930 if (backbuffer)
931 IDirect3DSurface9_Release(backbuffer);
932 IDirect3D9_Release(d3d);
933 DestroyWindow(window);
936 static void test_default_mixer_type_negotiation(void)
938 IMFMediaType *media_type, *media_type2;
939 IDirect3DDeviceManager9 *manager;
940 DXVA2_VideoProcessorCaps caps;
941 IMFVideoProcessor *processor;
942 IDirect3DDevice9 *device;
943 IMFMediaType *video_type;
944 IMFTransform *transform;
945 DWORD index, count;
946 GUID guid, *guids;
947 IDirect3D9 *d3d;
948 IUnknown *unk;
949 HWND window;
950 HRESULT hr;
951 UINT token;
953 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
954 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
956 hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
957 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
959 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
960 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
962 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
963 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
965 hr = MFCreateMediaType(&media_type);
966 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
968 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
969 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
971 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
972 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
974 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
975 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
977 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
978 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
980 /* Now try with device manager. */
982 window = create_window();
983 d3d = Direct3DCreate9(D3D_SDK_VERSION);
984 ok(!!d3d, "Failed to create a D3D object.\n");
985 if (!(device = create_device(d3d, window)))
987 skip("Failed to create a D3D device, skipping tests.\n");
988 goto done;
991 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
992 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
994 hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
995 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
997 /* Now manager is not initialized. */
998 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
999 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1001 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
1002 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1004 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1005 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1007 /* And now type description is incomplete. */
1008 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1009 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1010 IMFMediaType_Release(media_type);
1012 video_type = create_video_type(&MFVideoFormat_RGB32);
1014 /* Partially initialized type. */
1015 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1016 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1018 /* Only required data - frame size and uncompressed marker. */
1019 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1020 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1021 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1022 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1024 hr = IMFTransform_SetInputType(transform, 0, video_type, MFT_SET_TYPE_TEST_ONLY);
1025 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1027 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1028 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1030 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1033 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1034 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1035 ok(media_type == video_type, "Unexpected media type instance.\n");
1037 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
1038 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1039 ok(media_type == media_type2, "Unexpected media type instance.\n");
1040 IMFMediaType_Release(media_type);
1041 IMFMediaType_Release(media_type2);
1043 /* Check attributes on available output types. */
1044 index = 0;
1045 while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
1047 UINT64 frame_size;
1048 GUID subtype;
1049 UINT32 value;
1051 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
1052 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1053 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size);
1054 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1055 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
1056 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1058 IMFMediaType_Release(media_type);
1060 ok(index > 1, "Unexpected number of available types.\n");
1062 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&processor);
1063 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1065 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1066 todo_wine
1067 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1069 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
1070 todo_wine
1071 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1073 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1074 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1075 ok(media_type == video_type, "Unexpected pointer.\n");
1076 hr = IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&unk);
1077 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1078 IUnknown_Release(unk);
1079 IMFMediaType_Release(media_type);
1081 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1082 todo_wine
1083 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1085 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1086 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1088 hr = IMFTransform_SetOutputType(transform, 1, media_type, 0);
1089 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1091 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
1092 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1094 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1095 todo_wine
1096 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1098 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1099 todo_wine
1100 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1101 if (SUCCEEDED(hr))
1102 CoTaskMemFree(guids);
1104 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
1105 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1106 ok(media_type == media_type2, "Unexpected media type instance.\n");
1107 IMFMediaType_Release(media_type2);
1108 IMFMediaType_Release(media_type);
1110 IMFVideoProcessor_Release(processor);
1112 IMFMediaType_Release(video_type);
1114 IDirect3DDeviceManager9_Release(manager);
1116 IDirect3DDevice9_Release(device);
1118 done:
1119 IMFTransform_Release(transform);
1120 IDirect3D9_Release(d3d);
1121 DestroyWindow(window);
1124 static void test_default_presenter(void)
1126 IMFVideoDisplayControl *display_control;
1127 IMFVideoPresenter *presenter;
1128 IMFRateSupport *rate_support;
1129 IDirect3DDeviceManager9 *dm;
1130 IMFVideoDeviceID *deviceid;
1131 IUnknown *unk, *unk2;
1132 HWND hwnd, hwnd2;
1133 DWORD flags;
1134 float rate;
1135 HRESULT hr;
1136 GUID iid;
1138 hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter);
1139 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1141 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1142 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Failed to create default presenter, hr %#x.\n", hr);
1143 if (FAILED(hr))
1144 return;
1146 check_interface(presenter, &IID_IQualProp, TRUE);
1147 check_interface(presenter, &IID_IMFVideoPositionMapper, TRUE);
1148 check_interface(presenter, &IID_IMFTopologyServiceLookupClient, TRUE);
1149 check_interface(presenter, &IID_IMFVideoDisplayControl, TRUE);
1150 check_interface(presenter, &IID_IMFRateSupport, TRUE);
1151 check_interface(presenter, &IID_IMFGetService, TRUE);
1152 check_interface(presenter, &IID_IMFClockStateSink, TRUE);
1153 check_interface(presenter, &IID_IMFVideoPresenter, TRUE);
1154 check_interface(presenter, &IID_IMFVideoDeviceID, TRUE);
1155 check_interface(presenter, &IID_IMFQualityAdvise, TRUE);
1156 check_interface(presenter, &IID_IDirect3DDeviceManager9, TRUE);
1157 check_interface(presenter, &IID_IMFQualityAdviseLimits, TRUE);
1158 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
1159 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, TRUE);
1160 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPresenter, TRUE);
1161 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFClockStateSink, TRUE);
1162 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTopologyServiceLookupClient, TRUE);
1163 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IQualProp, TRUE);
1164 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFRateSupport, TRUE);
1165 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFGetService, TRUE);
1166 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDeviceID, TRUE);
1167 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdvise, TRUE);
1168 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdviseLimits, TRUE);
1169 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTransform, FALSE);
1170 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1171 check_service_interface(presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1173 /* Query arbitrary supported interface back from device manager wrapper. */
1174 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IDirect3DDeviceManager9, (void **)&dm);
1175 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1176 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IQualProp, (void **)&unk);
1177 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1178 IUnknown_Release(unk);
1179 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IUnknown, (void **)&unk);
1180 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1181 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IUnknown, (void **)&unk2);
1182 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1183 ok(unk == unk2, "Unexpected interface.\n");
1184 IUnknown_Release(unk2);
1185 IUnknown_Release(unk);
1186 IDirect3DDeviceManager9_Release(dm);
1188 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_MIXER_SERVICE, &IID_IUnknown, (void **)&unk);
1189 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#x.\n", hr);
1191 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
1192 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1194 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
1195 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1197 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
1198 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1199 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
1201 IMFVideoDeviceID_Release(deviceid);
1203 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
1204 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1206 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, NULL);
1207 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1209 flags = 123;
1210 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
1211 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1212 ok(!flags, "Unexpected rendering flags %#x.\n", flags);
1214 IMFVideoDisplayControl_Release(display_control);
1216 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1217 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1219 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1220 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1222 /* Video window */
1223 hwnd = create_window();
1224 ok(!!hwnd, "Failed to create a test window.\n");
1226 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, NULL);
1227 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1229 hwnd2 = hwnd;
1230 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1231 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1232 ok(hwnd2 == NULL, "Unexpected window %p.\n", hwnd2);
1234 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, NULL);
1235 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1237 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, (HWND)0x1);
1238 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1240 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1241 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1243 hwnd2 = NULL;
1244 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1245 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1246 ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
1248 /* Rate support. */
1249 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
1250 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1252 rate = 1.0f;
1253 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1254 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1255 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1257 rate = 1.0f;
1258 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1259 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1260 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1262 rate = 1.0f;
1263 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1264 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1265 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1267 rate = 1.0f;
1268 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1269 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1270 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1272 IMFRateSupport_Release(rate_support);
1274 IMFVideoPresenter_Release(presenter);
1276 DestroyWindow(hwnd);
1279 static void test_MFCreateVideoMixerAndPresenter(void)
1281 IUnknown *mixer, *presenter;
1282 HRESULT hr;
1284 hr = MFCreateVideoMixerAndPresenter(NULL, NULL, &IID_IUnknown, (void **)&mixer, &IID_IUnknown, (void **)&presenter);
1285 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1287 IUnknown_Release(mixer);
1288 IUnknown_Release(presenter);
1291 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
1292 REFIID riid, void **obj)
1294 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
1295 IsEqualIID(riid, &IID_IUnknown))
1297 *obj = iface;
1298 IMFVideoSampleAllocatorNotify_AddRef(iface);
1299 return S_OK;
1302 *obj = NULL;
1303 return E_NOINTERFACE;
1306 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
1308 return 2;
1311 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
1313 return 1;
1316 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
1318 return E_NOTIMPL;
1321 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
1323 test_notify_callback_QueryInterface,
1324 test_notify_callback_AddRef,
1325 test_notify_callback_Release,
1326 test_notify_callback_NotifyRelease,
1329 static void test_MFCreateVideoSampleAllocator(void)
1331 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
1332 IMFVideoSampleAllocatorCallback *allocator_cb;
1333 IMFMediaType *media_type, *video_type;
1334 IMFVideoSampleAllocator *allocator;
1335 IDirect3DDeviceManager9 *manager;
1336 IMFSample *sample, *sample2;
1337 IDirect3DSurface9 *surface;
1338 IDirect3DDevice9 *device;
1339 IMFMediaBuffer *buffer;
1340 LONG refcount, count;
1341 unsigned int token;
1342 IMFGetService *gs;
1343 IDirect3D9 *d3d;
1344 IUnknown *unk;
1345 HWND window;
1346 HRESULT hr;
1347 BYTE *data;
1349 hr = MFCreateVideoSampleAllocator(&IID_IUnknown, (void **)&unk);
1350 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1351 IUnknown_Release(unk);
1353 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1354 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1356 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
1357 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1359 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1360 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1362 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
1363 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1365 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1366 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1368 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
1369 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1371 count = 10;
1372 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1373 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1374 ok(!count, "Unexpected count %d.\n", count);
1376 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
1377 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1379 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1380 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1382 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
1383 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1385 hr = MFCreateMediaType(&media_type);
1386 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1388 /* It expects IMFVideoMediaType aka video major type. Exact return code is E_NOINTERFACE,
1389 likely coming from querying for IMFVideoMediaType. Does not seem valuable to match it. */
1390 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
1391 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1393 video_type = create_video_type(&MFVideoFormat_RGB32);
1395 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
1396 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1398 /* Frame size is required. */
1399 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1400 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1401 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1402 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1404 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1405 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1406 ok(count == 1, "Unexpected count %d.\n", count);
1408 sample = NULL;
1409 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1410 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1411 refcount = get_refcount(sample);
1413 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
1414 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
1416 /* Reinitialize with active sample. */
1417 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 4, video_type);
1418 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1419 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
1421 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1422 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1423 ok(count == 4, "Unexpected count %d.\n", count);
1425 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1426 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1428 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1429 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1431 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1433 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
1434 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#x.\n", hr);
1436 /* Device manager wasn't set, sample gets regular memory buffers. */
1437 if (SUCCEEDED(hr))
1439 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1440 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
1441 IMFGetService_Release(gs);
1444 IMFMediaBuffer_Release(buffer);
1446 IMFSample_Release(sample);
1448 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
1450 IMFVideoSampleAllocator_Release(allocator);
1452 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocatorCallback, (void **)&unk);
1453 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1454 IUnknown_Release(unk);
1456 /* Using device manager */
1457 window = create_window();
1458 d3d = Direct3DCreate9(D3D_SDK_VERSION);
1459 ok(!!d3d, "Failed to create a D3D object.\n");
1460 if (!(device = create_device(d3d, window)))
1462 skip("Failed to create a D3D device, skipping tests.\n");
1463 goto done;
1466 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
1467 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1468 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1469 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
1471 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1472 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1474 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
1475 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1477 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1478 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1479 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1480 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1482 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1483 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1485 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1486 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1488 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1489 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1491 check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE);
1492 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1493 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
1495 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1496 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1498 hr = IMFMediaBuffer_Unlock(buffer);
1499 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1501 IMFSample_Release(sample);
1503 IMFVideoSampleAllocator_Release(allocator);
1505 IMFMediaType_Release(media_type);
1506 IDirect3DDeviceManager9_Release(manager);
1507 IDirect3DDevice9_Release(device);
1508 done:
1509 IDirect3D9_Release(d3d);
1510 DestroyWindow(window);
1513 struct test_host
1515 IMFTopologyServiceLookup IMFTopologyServiceLookup_iface;
1516 IMediaEventSink IMediaEventSink_iface;
1517 IMFTransform *mixer;
1518 IMFVideoPresenter *presenter;
1521 static struct test_host *impl_from_test_host(IMFTopologyServiceLookup *iface)
1523 return CONTAINING_RECORD(iface, struct test_host, IMFTopologyServiceLookup_iface);
1526 static struct test_host *impl_from_test_host_events(IMediaEventSink *iface)
1528 return CONTAINING_RECORD(iface, struct test_host, IMediaEventSink_iface);
1531 static HRESULT WINAPI test_host_QueryInterface(IMFTopologyServiceLookup *iface, REFIID riid, void **obj)
1533 if (IsEqualIID(riid, &IID_IMFTopologyServiceLookup) ||
1534 IsEqualIID(riid, &IID_IUnknown))
1536 *obj = iface;
1537 IMFTopologyServiceLookup_AddRef(iface);
1538 return S_OK;
1541 *obj = NULL;
1542 return E_NOINTERFACE;
1545 static ULONG WINAPI test_host_AddRef(IMFTopologyServiceLookup *iface)
1547 return 2;
1550 static ULONG WINAPI test_host_Release(IMFTopologyServiceLookup *iface)
1552 return 1;
1555 static HRESULT WINAPI test_host_LookupService(IMFTopologyServiceLookup *iface,
1556 MF_SERVICE_LOOKUP_TYPE lookup_type, DWORD index, REFGUID service,
1557 REFIID riid, void **objects, DWORD *num_objects)
1559 struct test_host *host = impl_from_test_host(iface);
1561 ok(*num_objects == 1, "Unexpected number of requested objects %u\n", *num_objects);
1563 memset(objects, 0, *num_objects * sizeof(*objects));
1565 if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
1567 if (IsEqualIID(riid, &IID_IMFClock)) return E_FAIL;
1568 if (IsEqualIID(riid, &IID_IMediaEventSink))
1570 *objects = &host->IMediaEventSink_iface;
1571 IMediaEventSink_AddRef(&host->IMediaEventSink_iface);
1572 return S_OK;
1575 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1576 return E_UNEXPECTED;
1579 if (IsEqualGUID(service, &MR_VIDEO_MIXER_SERVICE))
1581 if (IsEqualIID(riid, &IID_IMFTransform))
1583 *objects = host->mixer;
1584 IMFTransform_AddRef(host->mixer);
1585 return S_OK;
1587 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1588 return E_UNEXPECTED;
1591 return E_NOTIMPL;
1594 static const IMFTopologyServiceLookupVtbl test_host_vtbl =
1596 test_host_QueryInterface,
1597 test_host_AddRef,
1598 test_host_Release,
1599 test_host_LookupService,
1602 static HRESULT WINAPI test_host_events_QueryInterface(IMediaEventSink *iface, REFIID riid, void **obj)
1604 struct test_host *host = impl_from_test_host_events(iface);
1605 return IMFTopologyServiceLookup_QueryInterface(&host->IMFTopologyServiceLookup_iface, riid, obj);
1608 static ULONG WINAPI test_host_events_AddRef(IMediaEventSink *iface)
1610 struct test_host *host = impl_from_test_host_events(iface);
1611 return IMFTopologyServiceLookup_AddRef(&host->IMFTopologyServiceLookup_iface);
1614 static ULONG WINAPI test_host_events_Release(IMediaEventSink *iface)
1616 struct test_host *host = impl_from_test_host_events(iface);
1617 return IMFTopologyServiceLookup_Release(&host->IMFTopologyServiceLookup_iface);
1620 static HRESULT WINAPI test_host_events_Notify(IMediaEventSink *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
1622 return S_OK;
1625 static const IMediaEventSinkVtbl test_host_events_vtbl =
1627 test_host_events_QueryInterface,
1628 test_host_events_AddRef,
1629 test_host_events_Release,
1630 test_host_events_Notify,
1633 static void init_test_host(struct test_host *host, IMFTransform *mixer, IMFVideoPresenter *presenter)
1635 host->IMFTopologyServiceLookup_iface.lpVtbl = &test_host_vtbl;
1636 host->IMediaEventSink_iface.lpVtbl = &test_host_events_vtbl;
1637 /* No need to keep references. */
1638 host->mixer = mixer;
1639 host->presenter = presenter;
1642 static void test_presenter_video_position(void)
1644 IMFTopologyServiceLookupClient *lookup_client;
1645 IMFVideoDisplayControl *display_control;
1646 IMFAttributes *mixer_attributes;
1647 MFVideoNormalizedRect src_rect;
1648 IMFVideoPresenter *presenter;
1649 struct test_host host;
1650 IMFTransform *mixer;
1651 RECT dst_rect;
1652 HRESULT hr;
1653 DWORD count;
1654 HWND hwnd;
1656 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1657 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1659 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1660 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1662 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1663 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1665 init_test_host(&host, mixer, presenter);
1667 /* Clear default mixer attributes, then attach presenter. */
1668 hr = IMFTransform_GetAttributes(mixer, &mixer_attributes);
1669 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1671 hr = IMFAttributes_DeleteAllItems(mixer_attributes);
1672 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1674 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1675 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1677 hr = IMFAttributes_GetCount(mixer_attributes, &count);
1678 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1679 ok(count == 1, "Unexpected count %u.\n", count);
1681 memset(&src_rect, 0, sizeof(src_rect));
1682 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1683 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1684 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1685 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1687 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1688 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1690 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &dst_rect);
1691 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1693 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, NULL);
1694 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1696 SetRect(&dst_rect, 1, 2, 3, 4);
1697 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1698 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1699 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1700 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1701 ok(dst_rect.left == 0 && dst_rect.right == 0 && dst_rect.top == 0 && dst_rect.bottom == 0,
1702 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1704 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, NULL);
1705 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1707 /* Setting position requires a window. */
1708 hwnd = create_window();
1709 ok(!!hwnd, "Failed to create a test window.\n");
1711 SetRect(&dst_rect, 0, 0, 10, 10);
1712 memset(&src_rect, 0, sizeof(src_rect));
1713 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, &dst_rect);
1714 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1716 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1717 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1719 SetRect(&dst_rect, 0, 0, 10, 10);
1720 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1721 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1723 SetRect(&dst_rect, 1, 2, 3, 4);
1724 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1726 ok(dst_rect.left == 0 && dst_rect.right == 10 && dst_rect.top == 0 && dst_rect.bottom == 10,
1727 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1729 set_rect(&src_rect, 0.0f, 0.0f, 2.0f, 1.0f);
1730 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1731 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1733 set_rect(&src_rect, -0.1f, 0.0f, 0.9f, 1.0f);
1734 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1735 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1737 /* Flipped source rectangle. */
1738 set_rect(&src_rect, 0.5f, 0.0f, 0.4f, 1.0f);
1739 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1740 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1742 set_rect(&src_rect, 0.0f, 0.5f, 0.4f, 0.1f);
1743 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1744 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1746 set_rect(&src_rect, 0.1f, 0.2f, 0.8f, 0.9f);
1747 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1748 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1750 /* Presenter updates mixer attribute. */
1751 memset(&src_rect, 0, sizeof(src_rect));
1752 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1753 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1754 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1755 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1757 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1758 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1759 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1760 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1762 SetRect(&dst_rect, 1, 2, 999, 1000);
1763 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1764 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1766 SetRect(&dst_rect, 0, 1, 3, 4);
1767 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1768 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1769 ok(dst_rect.left == 1 && dst_rect.right == 999 && dst_rect.top == 2 && dst_rect.bottom == 1000,
1770 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1772 /* Flipped destination rectangle. */
1773 SetRect(&dst_rect, 100, 1, 50, 1000);
1774 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1775 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1777 SetRect(&dst_rect, 1, 100, 100, 50);
1778 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1779 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1781 IMFVideoDisplayControl_Release(display_control);
1783 IMFTopologyServiceLookupClient_Release(lookup_client);
1784 IMFVideoPresenter_Release(presenter);
1785 IMFAttributes_Release(mixer_attributes);
1786 IMFTransform_Release(mixer);
1788 DestroyWindow(hwnd);
1791 static void test_presenter_native_video_size(void)
1793 IMFTopologyServiceLookupClient *lookup_client;
1794 IMFVideoDisplayControl *display_control;
1795 IMFVideoPresenter *presenter;
1796 struct test_host host;
1797 IMFTransform *mixer;
1798 SIZE size, ratio;
1799 HRESULT hr;
1800 IMFMediaType *video_type;
1801 IDirect3DDeviceManager9 *dm;
1803 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1804 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1806 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1807 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1809 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1810 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1812 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1815 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, NULL);
1816 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1818 memset(&size, 0xcc, sizeof(size));
1819 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, NULL);
1820 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1821 ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n");
1823 memset(&ratio, 0xcc, sizeof(ratio));
1824 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, &ratio);
1825 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1826 ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n");
1828 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1829 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1831 /* Configure mixer primary stream. */
1832 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1833 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1835 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)dm);
1836 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1838 IDirect3DDeviceManager9_Release(dm);
1840 video_type = create_video_type(&MFVideoFormat_RGB32);
1842 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1843 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1844 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1845 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1847 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1848 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1850 /* Native video size is cached on initialization. */
1851 init_test_host(&host, mixer, presenter);
1853 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1854 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1856 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1857 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1858 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1859 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1860 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1862 /* Update input type. */
1863 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)320 << 32 | 240);
1864 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1866 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1867 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1869 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1870 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1871 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1872 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1873 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1875 /* Negotiating types updates native video size. */
1876 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
1877 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1879 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1880 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1881 ok(size.cx == 320 && size.cy == 240, "Unexpected size %u x %u.\n", size.cx, size.cy);
1882 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1883 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1885 IMFMediaType_Release(video_type);
1886 IMFVideoDisplayControl_Release(display_control);
1887 IMFVideoPresenter_Release(presenter);
1888 IMFTransform_Release(mixer);
1891 static void test_presenter_ar_mode(void)
1893 IMFVideoDisplayControl *display_control;
1894 HRESULT hr;
1895 DWORD mode;
1897 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
1898 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1900 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, NULL);
1901 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1903 mode = 0;
1904 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
1905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1906 ok(mode == (MFVideoARMode_PreservePicture | MFVideoARMode_PreservePixel), "Unexpected mode %#x.\n", mode);
1908 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, 0x100);
1909 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1911 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_Mask);
1912 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1914 mode = 0;
1915 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
1916 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1917 ok(mode == MFVideoARMode_Mask, "Unexpected mode %#x.\n", mode);
1919 IMFVideoDisplayControl_Release(display_control);
1922 static void test_presenter_video_window(void)
1924 D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
1925 IMFVideoDisplayControl *display_control;
1926 IDirect3DDeviceManager9 *dm;
1927 IDirect3DDevice9 *d3d_device;
1928 HANDLE hdevice;
1929 HRESULT hr;
1930 IDirect3DSwapChain9 *swapchain;
1931 D3DPRESENT_PARAMETERS present_params = { 0 };
1932 HWND window;
1934 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
1935 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1937 hr = MFGetService((IUnknown *)display_control, &MR_VIDEO_ACCELERATION_SERVICE,
1938 &IID_IDirect3DDeviceManager9, (void **)&dm);
1940 hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &hdevice);
1941 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1943 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
1944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1946 hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
1947 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1948 ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
1950 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
1951 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1953 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
1954 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1956 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
1957 ok(present_params.Windowed, "Unexpected windowed mode.\n");
1958 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
1959 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
1960 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
1962 IDirect3DSwapChain9_Release(swapchain);
1963 IDirect3DDevice9_Release(d3d_device);
1965 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
1966 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1968 /* Setting window. */
1969 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window);
1970 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1971 ok(!window, "Unexpected window %p.\n", window);
1973 window = create_window();
1975 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
1976 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1978 /* Device is not recreated or reset on window change. */
1979 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
1980 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1982 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
1983 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1985 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
1986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1988 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
1989 ok(present_params.Windowed, "Unexpected windowed mode.\n");
1990 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
1991 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
1992 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
1994 IDirect3DSwapChain9_Release(swapchain);
1995 IDirect3DDevice9_Release(d3d_device);
1997 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
1998 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2000 hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, hdevice);
2001 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2003 IMFVideoDisplayControl_Release(display_control);
2005 DestroyWindow(window);
2008 static void test_presenter_quality_control(void)
2010 IMFQualityAdviseLimits *qa_limits;
2011 IMFVideoPresenter *presenter;
2012 MF_QUALITY_DROP_MODE mode;
2013 IMFQualityAdvise *advise;
2014 MF_QUALITY_LEVEL level;
2015 HRESULT hr;
2017 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2018 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2020 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdviseLimits, (void **)&qa_limits);
2021 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2023 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdvise, (void **)&advise);
2024 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2026 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, NULL);
2027 todo_wine
2028 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2030 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, &mode);
2031 todo_wine
2032 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2033 if (SUCCEEDED(hr))
2034 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2036 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, NULL);
2037 todo_wine
2038 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2040 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, &level);
2041 todo_wine
2042 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2043 if (SUCCEEDED(hr))
2044 ok(level == MF_QUALITY_NORMAL, "Unexpected level %d.\n", level);
2046 IMFQualityAdviseLimits_Release(qa_limits);
2048 todo_wine {
2049 mode = 1;
2050 hr = IMFQualityAdvise_GetDropMode(advise, &mode);
2051 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2052 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2054 level = 1;
2055 hr = IMFQualityAdvise_GetQualityLevel(advise, &level);
2056 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2057 ok(level == MF_QUALITY_NORMAL, "Unexpected mode %d.\n", level);
2059 hr = IMFQualityAdvise_SetDropMode(advise, MF_DROP_MODE_1);
2060 ok(hr == MF_E_NO_MORE_DROP_MODES, "Unexpected hr %#x.\n", hr);
2062 hr = IMFQualityAdvise_SetQualityLevel(advise, MF_QUALITY_NORMAL_MINUS_1);
2063 ok(hr == MF_E_NO_MORE_QUALITY_LEVELS, "Unexpected hr %#x.\n", hr);
2066 IMFQualityAdvise_Release(advise);
2068 IMFVideoPresenter_Release(presenter);
2071 static void get_output_aperture(IMFTransform *mixer, SIZE *frame_size, MFVideoArea *aperture)
2073 IMFMediaType *media_type;
2074 UINT64 size;
2075 HRESULT hr;
2077 memset(frame_size, 0xcc, sizeof(*frame_size));
2078 memset(aperture, 0xcc, sizeof(*aperture));
2080 hr = IMFTransform_GetOutputCurrentType(mixer, 0, &media_type);
2081 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2083 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &size);
2084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2086 frame_size->cx = size >> 32;
2087 frame_size->cy = size;
2089 hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)aperture, sizeof(*aperture), NULL);
2090 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2092 IMFMediaType_Release(media_type);
2095 static void test_presenter_media_type(void)
2097 IMFTopologyServiceLookupClient *lookup_client;
2098 IMFVideoPresenter *presenter;
2099 struct test_host host;
2100 IMFMediaType *input_type;
2101 IDirect3DDeviceManager9 *manager;
2102 HRESULT hr;
2103 IMFTransform *mixer;
2104 IDirect3D9 *d3d;
2105 IDirect3DDevice9 *device;
2106 unsigned int token;
2107 SIZE frame_size;
2108 HWND window;
2109 MFVideoArea aperture;
2110 IMFVideoDisplayControl *display_control;
2111 RECT dst;
2113 window = create_window();
2114 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2115 ok(!!d3d, "Failed to create a D3D object.\n");
2116 if (!(device = create_device(d3d, window)))
2118 skip("Failed to create a D3D device, skipping tests.\n");
2119 goto done;
2122 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2123 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2125 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2126 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2128 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2129 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2131 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2132 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2134 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2135 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2137 input_type = create_video_type(&MFVideoFormat_RGB32);
2139 hr = IMFMediaType_SetUINT64(input_type, &MF_MT_FRAME_SIZE, (UINT64)100 << 32 | 50);
2140 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2141 hr = IMFMediaType_SetUINT32(input_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2142 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2144 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2145 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2147 hr = IMFTransform_SetInputType(mixer, 0, input_type, 0);
2148 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2150 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2151 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2153 init_test_host(&host, mixer, presenter);
2155 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
2156 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2158 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2159 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2161 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2162 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2164 get_output_aperture(mixer, &frame_size, &aperture);
2165 ok(frame_size.cx == 100 && frame_size.cy == 50, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2166 ok(aperture.Area.cx == 100 && aperture.Area.cy == 50, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2167 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2168 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2170 SetRect(&dst, 1, 2, 200, 300);
2171 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
2172 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2174 get_output_aperture(mixer, &frame_size, &aperture);
2175 todo_wine {
2176 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2177 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2179 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2180 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2182 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
2183 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2185 get_output_aperture(mixer, &frame_size, &aperture);
2186 todo_wine {
2187 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2188 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2190 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2191 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2193 IMFVideoDisplayControl_Release(display_control);
2194 IMFVideoPresenter_Release(presenter);
2195 IMFTransform_Release(mixer);
2197 done:
2198 IDirect3D9_Release(d3d);
2199 DestroyWindow(window);
2202 static void test_mixer_output_rectangle(void)
2204 IMFVideoMixerControl *mixer_control;
2205 MFVideoNormalizedRect rect;
2206 IMFTransform *mixer;
2207 HRESULT hr;
2209 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2210 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2212 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2213 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2215 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, NULL);
2216 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2218 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
2219 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, &rect);
2220 ok(hr == S_OK, "Failed to get output rect, hr %#x.\n", hr);
2221 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
2222 "Unexpected rectangle.\n");
2224 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, &rect);
2225 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2227 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, NULL);
2228 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2230 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, &rect);
2231 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2233 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, NULL);
2234 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2236 /* Wrong bounds. */
2237 set_rect(&rect, 0.0f, 0.0f, 1.1f, 1.0f);
2238 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2239 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2241 set_rect(&rect, -0.1f, 0.0f, 0.5f, 1.0f);
2242 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2243 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2245 /* Flipped. */
2246 set_rect(&rect, 1.0f, 0.0f, 0.0f, 1.0f);
2247 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2248 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2250 set_rect(&rect, 0.0f, 1.0f, 1.0f, 0.5f);
2251 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2252 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2254 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, NULL);
2255 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2257 IMFVideoMixerControl_Release(mixer_control);
2258 IMFTransform_Release(mixer);
2261 static void test_mixer_zorder(void)
2263 IMFVideoMixerControl *mixer_control;
2264 IMFTransform *mixer;
2265 DWORD ids[2];
2266 DWORD value;
2267 HRESULT hr;
2269 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2270 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2272 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2273 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2275 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, NULL);
2276 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2278 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, NULL);
2279 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2281 value = 1;
2282 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, &value);
2283 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2284 ok(!value, "Unexpected value %u.\n", value);
2286 value = 1;
2287 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2288 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2290 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 1);
2291 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2293 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 1);
2294 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2296 /* Exceeds maximum stream number. */
2297 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 20);
2298 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2300 value = 1;
2301 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2302 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2304 value = 0;
2305 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2306 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2307 ok(value == 1, "Unexpected zorder %u.\n", value);
2309 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 0);
2310 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
2312 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 2);
2313 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2315 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 0);
2316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2318 value = 2;
2319 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2320 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2322 value = 0;
2323 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2324 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2325 ok(value == 2, "Unexpected zorder %u.\n", value);
2327 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 2, 1);
2328 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2330 value = 3;
2331 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2332 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2334 value = 0;
2335 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 3, &value);
2336 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2337 ok(value == 3, "Unexpected zorder %u.\n", value);
2339 hr = IMFTransform_DeleteInputStream(mixer, 1);
2340 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2341 hr = IMFTransform_DeleteInputStream(mixer, 2);
2342 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2343 hr = IMFTransform_DeleteInputStream(mixer, 3);
2344 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2346 ids[0] = 2;
2347 ids[1] = 1;
2348 hr = IMFTransform_AddInputStreams(mixer, 2, ids);
2349 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2351 value = 0;
2352 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2353 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2354 ok(value == 2, "Unexpected zorder %u.\n", value);
2356 value = 0;
2357 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2358 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2359 ok(value == 1, "Unexpected zorder %u.\n", value);
2361 IMFVideoMixerControl_Release(mixer_control);
2362 IMFTransform_Release(mixer);
2365 static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, unsigned int width,
2366 unsigned int height)
2368 IDirectXVideoAccelerationService *service;
2369 IDirect3DSurface9 *surface = NULL;
2370 IDirect3DDevice9 *device;
2371 HANDLE handle;
2372 HRESULT hr;
2374 hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle);
2375 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2377 hr = IDirect3DDeviceManager9_LockDevice(manager, handle, &device, TRUE);
2378 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2380 hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
2381 (void **)&service);
2382 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2384 hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, D3DFMT_A8R8G8B8,
2385 D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &surface, NULL);
2386 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2388 IDirectXVideoAccelerationService_Release(service);
2390 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00));
2391 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2393 IDirect3DDevice9_Release(device);
2395 hr = IDirect3DDeviceManager9_UnlockDevice(manager, handle, FALSE);
2396 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2398 hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
2399 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2401 return surface;
2404 /* Format is assumed as 32bpp */
2405 static DWORD get_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
2407 D3DLOCKED_RECT locked_rect = { 0 };
2408 D3DSURFACE_DESC desc;
2409 DWORD *row, color;
2410 HRESULT hr;
2412 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2413 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2414 ok(x < desc.Width && y < desc.Height, "Invalid coordinate.\n");
2415 if (x >= desc.Width || y >= desc.Height) return 0;
2417 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2418 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2420 row = (DWORD *)((char *)locked_rect.pBits + y * locked_rect.Pitch);
2421 color = row[x];
2423 hr = IDirect3DSurface9_UnlockRect(surface);
2424 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2426 return color;
2429 static void test_mixer_samples(void)
2431 IDirect3DDeviceManager9 *manager;
2432 MFT_OUTPUT_DATA_BUFFER buffers[2];
2433 IMFVideoProcessor *processor;
2434 IDirect3DSurface9 *surface;
2435 IMFDesiredSample *desired;
2436 IDirect3DDevice9 *device;
2437 IMFMediaType *video_type;
2438 DWORD count, flags, color, status;
2439 IMFTransform *mixer;
2440 IMFSample *sample, *sample2;
2441 IDirect3D9 *d3d;
2442 HWND window;
2443 UINT token;
2444 HRESULT hr;
2445 LONGLONG pts, duration;
2447 window = create_window();
2448 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2449 ok(!!d3d, "Failed to create a D3D object.\n");
2450 if (!(device = create_device(d3d, window)))
2452 skip("Failed to create a D3D device, skipping tests.\n");
2453 goto done;
2456 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2457 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2459 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoProcessor, (void **)&processor);
2460 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2462 hr = IMFTransform_GetInputStatus(mixer, 0, NULL);
2463 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2465 hr = IMFTransform_GetInputStatus(mixer, 1, NULL);
2466 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2468 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2469 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2471 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2472 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2474 hr = IMFTransform_GetOutputStatus(mixer, NULL);
2475 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2477 hr = IMFTransform_GetOutputStatus(mixer, &status);
2478 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2480 /* Configure device and media types. */
2481 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2482 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2484 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2485 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
2487 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2488 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2490 video_type = create_video_type(&MFVideoFormat_RGB32);
2492 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
2493 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2494 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2495 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2497 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
2498 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2500 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2501 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2503 hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0);
2504 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2506 status = 0;
2507 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2508 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2509 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2511 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2512 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2514 status = ~0u;
2515 hr = IMFTransform_GetOutputStatus(mixer, &status);
2516 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2517 ok(!status, "Unexpected status %#x.\n", status);
2519 IMFMediaType_Release(video_type);
2521 memset(buffers, 0, sizeof(buffers));
2522 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2523 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2525 /* It needs a sample with a backing surface. */
2526 hr = MFCreateSample(&sample);
2527 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2529 buffers[0].pSample = sample;
2530 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2531 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2533 IMFSample_Release(sample);
2535 surface = create_surface(manager, 64, 64);
2537 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
2538 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2540 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired);
2541 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2543 buffers[0].pSample = sample;
2544 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2545 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2547 color = get_surface_color(surface, 0, 0);
2548 ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#x.\n", color);
2550 /* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
2551 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
2553 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2554 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2556 color = get_surface_color(surface, 0, 0);
2557 ok(!color, "Unexpected color %#x.\n", color);
2559 hr = IMFVideoProcessor_SetBackgroundColor(processor, RGB(0, 0, 255));
2560 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2562 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2563 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2565 color = get_surface_color(surface, 0, 0);
2566 ok(!color, "Unexpected color %#x.\n", color);
2568 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
2569 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2571 buffers[1].pSample = sample;
2572 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
2573 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2575 buffers[0].dwStreamID = 1;
2576 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2577 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2579 IMFDesiredSample_Clear(desired);
2581 hr = IMFTransform_ProcessInput(mixer, 0, NULL, 0);
2582 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2584 hr = IMFTransform_ProcessInput(mixer, 5, NULL, 0);
2585 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2587 status = 0;
2588 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2589 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2590 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2592 status = ~0u;
2593 hr = IMFTransform_GetOutputStatus(mixer, &status);
2594 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2595 ok(!status, "Unexpected status %#x.\n", status);
2597 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2598 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2600 status = ~0u;
2601 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2602 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2603 ok(!status, "Unexpected status %#x.\n", status);
2605 hr = IMFTransform_GetOutputStatus(mixer, &status);
2606 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2607 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#x.\n", status);
2609 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2610 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
2612 hr = IMFTransform_ProcessInput(mixer, 5, sample, 0);
2613 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2615 /* ProcessOutput() sets sample time and duration. */
2616 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample2);
2617 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2619 hr = IMFSample_SetUINT32(sample2, &IID_IMFSample, 1);
2620 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2622 hr = IMFSample_SetSampleFlags(sample2, 0x123);
2623 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2625 hr = IMFSample_GetSampleTime(sample2, &pts);
2626 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2628 hr = IMFSample_GetSampleDuration(sample2, &duration);
2629 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2631 hr = IMFSample_SetSampleTime(sample, 0);
2632 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2634 hr = IMFSample_SetSampleDuration(sample, 0);
2635 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2637 memset(buffers, 0, sizeof(buffers));
2638 buffers[0].pSample = sample2;
2639 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2640 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2642 hr = IMFSample_GetSampleTime(sample2, &pts);
2643 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2644 ok(!pts, "Unexpected sample time.\n");
2646 hr = IMFSample_GetSampleDuration(sample2, &duration);
2647 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2648 ok(!duration, "Unexpected duration\n");
2650 /* Flags are not copied. */
2651 hr = IMFSample_GetSampleFlags(sample2, &flags);
2652 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2653 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2655 /* Attributes are not removed. */
2656 hr = IMFSample_GetCount(sample2, &count);
2657 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2658 ok(count == 1, "Unexpected attribute count %u.\n", count);
2660 hr = IMFSample_GetCount(sample, &count);
2661 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2662 ok(!count, "Unexpected attribute count %u.\n", count);
2664 IMFSample_Release(sample2);
2666 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_DRAIN, 0);
2667 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2669 IMFSample_Release(sample);
2671 IDirect3DSurface9_Release(surface);
2673 IMFVideoProcessor_Release(processor);
2674 IMFTransform_Release(mixer);
2676 IDirect3DDevice9_Release(device);
2677 IDirect3DDeviceManager9_Release(manager);
2679 done:
2680 IDirect3D9_Release(d3d);
2681 DestroyWindow(window);
2684 START_TEST(evr)
2686 CoInitialize(NULL);
2688 test_aggregation();
2689 test_interfaces();
2690 test_enum_pins();
2691 test_find_pin();
2692 test_pin_info();
2693 test_default_mixer();
2694 test_default_mixer_type_negotiation();
2695 test_surface_sample();
2696 test_default_presenter();
2697 test_MFCreateVideoMixerAndPresenter();
2698 test_MFCreateVideoSampleAllocator();
2699 test_presenter_video_position();
2700 test_presenter_native_video_size();
2701 test_presenter_ar_mode();
2702 test_presenter_video_window();
2703 test_presenter_quality_control();
2704 test_presenter_media_type();
2705 test_mixer_output_rectangle();
2706 test_mixer_zorder();
2707 test_mixer_samples();
2709 CoUninitialize();