evr/mixer: Implement GetOutputStatus().
[wine.git] / dlls / evr / tests / evr.c
blob7cf127d4d8c1010b13a1181f946932d14037200d
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 static void test_interfaces(void)
236 IBaseFilter *filter = create_evr();
237 ULONG ref;
239 todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
240 check_interface(filter, &IID_IBaseFilter, TRUE);
241 check_interface(filter, &IID_IMediaFilter, TRUE);
242 check_interface(filter, &IID_IMediaPosition, TRUE);
243 check_interface(filter, &IID_IMediaSeeking, TRUE);
244 check_interface(filter, &IID_IPersist, TRUE);
245 check_interface(filter, &IID_IUnknown, TRUE);
247 check_interface(filter, &IID_IBasicAudio, FALSE);
248 check_interface(filter, &IID_IBasicVideo, FALSE);
249 check_interface(filter, &IID_IDirectXVideoMemoryConfiguration, FALSE);
250 check_interface(filter, &IID_IMemInputPin, FALSE);
251 check_interface(filter, &IID_IPersistPropertyBag, FALSE);
252 check_interface(filter, &IID_IPin, FALSE);
253 check_interface(filter, &IID_IReferenceClock, FALSE);
254 check_interface(filter, &IID_IVideoWindow, FALSE);
256 ref = IBaseFilter_Release(filter);
257 ok(!ref, "Got unexpected refcount %d.\n", ref);
260 static void test_enum_pins(void)
262 IBaseFilter *filter = create_evr();
263 IEnumPins *enum1, *enum2;
264 ULONG count, ref;
265 IPin *pins[2];
266 HRESULT hr;
268 ref = get_refcount(filter);
269 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
271 hr = IBaseFilter_EnumPins(filter, NULL);
272 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
274 hr = IBaseFilter_EnumPins(filter, &enum1);
275 ok(hr == S_OK, "Got hr %#x.\n", hr);
276 ref = get_refcount(filter);
277 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
278 ref = get_refcount(enum1);
279 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
281 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
282 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
284 hr = IEnumPins_Next(enum1, 1, pins, NULL);
285 ok(hr == S_OK, "Got hr %#x.\n", hr);
286 ref = get_refcount(filter);
287 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
288 ref = get_refcount(pins[0]);
289 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
290 ref = get_refcount(enum1);
291 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
292 IPin_Release(pins[0]);
293 ref = get_refcount(filter);
294 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
296 hr = IEnumPins_Next(enum1, 1, pins, NULL);
297 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
299 hr = IEnumPins_Reset(enum1);
300 ok(hr == S_OK, "Got hr %#x.\n", hr);
302 hr = IEnumPins_Next(enum1, 1, pins, &count);
303 ok(hr == S_OK, "Got hr %#x.\n", hr);
304 ok(count == 1, "Got count %u.\n", count);
305 IPin_Release(pins[0]);
307 hr = IEnumPins_Next(enum1, 1, pins, &count);
308 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
309 ok(!count, "Got count %u.\n", count);
311 hr = IEnumPins_Reset(enum1);
312 ok(hr == S_OK, "Got hr %#x.\n", hr);
314 hr = IEnumPins_Next(enum1, 2, pins, NULL);
315 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
317 hr = IEnumPins_Next(enum1, 2, pins, &count);
318 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
319 ok(count == 1, "Got count %u.\n", count);
320 IPin_Release(pins[0]);
322 hr = IEnumPins_Reset(enum1);
323 ok(hr == S_OK, "Got hr %#x.\n", hr);
325 hr = IEnumPins_Clone(enum1, &enum2);
326 ok(hr == S_OK, "Got hr %#x.\n", hr);
328 hr = IEnumPins_Skip(enum1, 2);
329 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
331 hr = IEnumPins_Skip(enum1, 1);
332 ok(hr == S_OK, "Got hr %#x.\n", hr);
334 hr = IEnumPins_Skip(enum1, 1);
335 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
337 hr = IEnumPins_Next(enum1, 1, pins, NULL);
338 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
340 hr = IEnumPins_Next(enum2, 1, pins, NULL);
341 ok(hr == S_OK, "Got hr %#x.\n", hr);
342 IPin_Release(pins[0]);
344 IEnumPins_Release(enum2);
345 IEnumPins_Release(enum1);
346 ref = IBaseFilter_Release(filter);
347 ok(!ref, "Got outstanding refcount %d.\n", ref);
350 static void test_find_pin(void)
352 IBaseFilter *filter = create_evr();
353 IEnumPins *enum_pins;
354 IPin *pin, *pin2;
355 HRESULT hr;
356 ULONG ref;
358 hr = IBaseFilter_EnumPins(filter, &enum_pins);
359 ok(hr == S_OK, "Got hr %#x.\n", hr);
361 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
362 ok(hr == S_OK, "Got hr %#x.\n", hr);
363 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
364 ok(hr == S_OK, "Got hr %#x.\n", hr);
365 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
366 IPin_Release(pin2);
367 IPin_Release(pin);
369 IEnumPins_Release(enum_pins);
370 ref = IBaseFilter_Release(filter);
371 ok(!ref, "Got outstanding refcount %d.\n", ref);
374 static void test_pin_info(void)
376 IBaseFilter *filter = create_evr();
377 PIN_DIRECTION dir;
378 PIN_INFO info;
379 HRESULT hr;
380 WCHAR *id;
381 ULONG ref;
382 IPin *pin;
384 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
385 ok(hr == S_OK, "Got hr %#x.\n", hr);
386 ref = get_refcount(filter);
387 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
388 ref = get_refcount(pin);
389 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
391 hr = IPin_QueryPinInfo(pin, &info);
392 ok(hr == S_OK, "Got hr %#x.\n", hr);
393 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
394 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
395 ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
396 ref = get_refcount(filter);
397 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
398 ref = get_refcount(pin);
399 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
400 IBaseFilter_Release(info.pFilter);
402 hr = IPin_QueryDirection(pin, &dir);
403 ok(hr == S_OK, "Got hr %#x.\n", hr);
404 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
406 hr = IPin_QueryId(pin, &id);
407 ok(hr == S_OK, "Got hr %#x.\n", hr);
408 ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
409 CoTaskMemFree(id);
411 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
412 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
414 IPin_Release(pin);
415 ref = IBaseFilter_Release(filter);
416 ok(!ref, "Got outstanding refcount %d.\n", ref);
419 static IMFMediaType * create_video_type(const GUID *subtype)
421 IMFMediaType *video_type;
422 HRESULT hr;
424 hr = MFCreateMediaType(&video_type);
425 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
427 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
428 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
430 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
431 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
433 return video_type;
436 static void test_default_mixer(void)
438 DWORD input_min, input_max, output_min, output_max;
439 IMFAttributes *attributes, *attributes2;
440 IMFVideoMixerControl2 *mixer_control2;
441 MFT_OUTPUT_STREAM_INFO output_info;
442 MFT_INPUT_STREAM_INFO input_info;
443 DWORD input_count, output_count;
444 IMFVideoProcessor *processor;
445 IMFVideoDeviceID *deviceid;
446 MFVideoNormalizedRect rect;
447 DWORD input_id, output_id;
448 IMFTransform *transform;
449 DXVA2_ValueRange range;
450 DXVA2_Fixed32 dxva_value;
451 DWORD flags, value, count;
452 IMFGetService *gs;
453 COLORREF color;
454 unsigned int i;
455 DWORD ids[16];
456 IUnknown *unk;
457 GUID *guids;
458 HRESULT hr;
459 IID iid;
461 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
462 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
464 hr = IMFTransform_QueryInterface(transform, &IID_IMFQualityAdvise, (void **)&unk);
465 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
466 IUnknown_Release(unk);
468 hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
469 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
470 IUnknown_Release(unk);
472 hr = IMFTransform_QueryInterface(transform, &IID_IMFGetService, (void **)&gs);
473 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
475 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerBitmap, (void **)&unk);
476 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
477 IUnknown_Release(unk);
479 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, (void **)&processor);
480 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
482 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, (void **)&unk);
483 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
484 IUnknown_Release(unk);
486 if (SUCCEEDED(IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl2, (void **)&mixer_control2)))
488 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, NULL);
489 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
491 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, &flags);
492 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
493 ok(!flags, "Unexpected flags %#x.\n", flags);
495 IMFVideoMixerControl2_Release(mixer_control2);
498 hr = IMFVideoProcessor_GetBackgroundColor(processor, NULL);
499 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
501 color = 1;
502 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
503 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
504 ok(!color, "Unexpected color %#x.\n", color);
506 hr = IMFVideoProcessor_SetBackgroundColor(processor, 0x00121212);
507 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
509 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
510 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
511 ok(color == 0x121212, "Unexpected color %#x.\n", color);
513 hr = IMFVideoProcessor_GetFilteringRange(processor, DXVA2_DetailFilterChromaLevel, &range);
514 todo_wine
515 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
517 hr = IMFVideoProcessor_GetFilteringValue(processor, DXVA2_DetailFilterChromaLevel, &dxva_value);
518 todo_wine
519 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
521 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
522 todo_wine
523 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
525 IMFVideoProcessor_Release(processor);
527 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoPositionMapper, (void **)&unk);
528 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
529 IUnknown_Release(unk);
531 IMFGetService_Release(gs);
533 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoMixerBitmap, (void **)&unk);
534 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
535 IUnknown_Release(unk);
537 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoPositionMapper, (void **)&unk);
538 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
539 IUnknown_Release(unk);
541 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&unk);
542 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
543 IUnknown_Release(unk);
545 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoMixerControl, (void **)&unk);
546 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
547 IUnknown_Release(unk);
549 hr = IMFTransform_SetOutputBounds(transform, 100, 10);
550 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
552 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid);
553 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
555 hr = IMFTransform_GetAttributes(transform, NULL);
556 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
558 hr = IMFTransform_GetAttributes(transform, &attributes);
559 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
561 hr = IMFTransform_GetAttributes(transform, &attributes2);
562 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
563 ok(attributes == attributes2, "Unexpected attributes instance.\n");
564 IMFAttributes_Release(attributes2);
566 hr = IMFTransform_QueryInterface(transform, &IID_IMFAttributes, (void **)&attributes2);
567 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
568 ok(attributes != attributes2, "Unexpected attributes instance.\n");
570 hr = IMFAttributes_QueryInterface(attributes2, &IID_IMFTransform, (void **)&unk);
571 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
572 IUnknown_Release(unk);
574 hr = IMFAttributes_GetCount(attributes2, &count);
575 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
576 ok(count == 1, "Unexpected attribute count %u.\n", count);
578 value = 0;
579 hr = IMFAttributes_GetUINT32(attributes2, &MF_SA_D3D_AWARE, &value);
580 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
581 ok(value == 1, "Unexpected value %d.\n", value);
583 IMFAttributes_Release(attributes2);
585 hr = IMFAttributes_GetCount(attributes, &count);
586 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
587 ok(count == 1, "Unexpected attribute count %u.\n", count);
589 memset(&rect, 0, sizeof(rect));
590 hr = IMFAttributes_GetBlob(attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&rect, sizeof(rect), NULL);
591 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
592 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
593 "Unexpected zoom rect (%f, %f) - (%f, %f).\n", rect.left, rect.top, rect.right, rect.bottom);
595 IMFAttributes_Release(attributes);
597 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
598 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
600 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
601 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
602 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
604 IMFVideoDeviceID_Release(deviceid);
606 /* Stream configuration. */
607 input_count = output_count = 0;
608 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
609 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
610 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
612 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
613 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
614 ok(input_min == 1 && input_max == 16 && output_min == 1 && output_max == 1, "Unexpected stream limits %u/%u, %u/%u.\n",
615 input_min, input_max, output_min, output_max);
617 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
618 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
620 hr = IMFTransform_GetOutputStreamInfo(transform, 1, &output_info);
621 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
623 memset(&input_info, 0xcc, sizeof(input_info));
624 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
625 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
627 memset(&output_info, 0xcc, sizeof(output_info));
628 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
629 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
630 ok(!(output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)),
631 "Unexpected output flags %#x.\n", output_info.dwFlags);
633 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
634 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
635 ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
637 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
638 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
640 hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
641 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
643 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
644 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
646 hr = IMFTransform_AddInputStreams(transform, 16, NULL);
647 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
649 hr = IMFTransform_AddInputStreams(transform, 16, ids);
650 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
652 memset(ids, 0, sizeof(ids));
653 hr = IMFTransform_AddInputStreams(transform, 15, ids);
654 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
656 for (i = 0; i < ARRAY_SIZE(ids); ++i)
657 ids[i] = i + 1;
659 hr = IMFTransform_AddInputStreams(transform, 15, ids);
660 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
662 input_count = output_count = 0;
663 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
664 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
665 ok(input_count == 16 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
667 memset(&input_info, 0, sizeof(input_info));
668 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
669 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
670 ok((input_info.dwFlags & (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL)) ==
671 (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL), "Unexpected flags %#x.\n", input_info.dwFlags);
673 attributes = NULL;
674 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
675 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
676 hr = IMFAttributes_GetCount(attributes, &count);
677 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
678 ok(count == 1, "Unexpected count %u.\n", count);
679 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &count);
680 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
681 ok(count == 1, "Unexpected count %u.\n", count);
682 ok(!!attributes, "Unexpected attributes.\n");
684 attributes2 = NULL;
685 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
686 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
687 ok(attributes == attributes2, "Unexpected instance.\n");
689 IMFAttributes_Release(attributes2);
690 IMFAttributes_Release(attributes);
692 attributes = NULL;
693 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
694 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
695 ok(!!attributes, "Unexpected attributes.\n");
696 IMFAttributes_Release(attributes);
698 hr = IMFTransform_DeleteInputStream(transform, 0);
699 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
701 hr = IMFTransform_DeleteInputStream(transform, 1);
702 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
704 input_count = output_count = 0;
705 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
706 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
707 ok(input_count == 15 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
709 IMFTransform_Release(transform);
711 hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
712 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
714 hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
715 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
716 IMFTransform_Release(transform);
719 static void test_surface_sample(void)
721 IDirect3DSurface9 *backbuffer = NULL, *surface;
722 IMFDesiredSample *desired_sample;
723 IMFMediaBuffer *buffer, *buffer2;
724 LONGLONG duration, time1, time2;
725 IDirect3DSwapChain9 *swapchain;
726 DWORD flags, count, length;
727 IDirect3DDevice9 *device;
728 IMFSample *sample;
729 IDirect3D9 *d3d;
730 IUnknown *unk;
731 HWND window;
732 HRESULT hr;
733 BYTE *data;
735 window = create_window();
736 d3d = Direct3DCreate9(D3D_SDK_VERSION);
737 ok(!!d3d, "Failed to create a D3D object.\n");
738 if (!(device = create_device(d3d, window)))
740 skip("Failed to create a D3D device, skipping tests.\n");
741 goto done;
744 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
745 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
747 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
748 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
749 ok(backbuffer != NULL, "The back buffer is NULL\n");
751 IDirect3DSwapChain9_Release(swapchain);
753 hr = MFCreateVideoSampleFromSurface(NULL, &sample);
754 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
755 IMFSample_Release(sample);
757 hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample);
758 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
760 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
761 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
762 IUnknown_Release(unk);
764 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired_sample);
765 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
767 hr = IMFSample_GetCount(sample, &count);
768 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
769 ok(!count, "Unexpected attribute count %u.\n", count);
771 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, NULL);
772 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
774 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, &time2);
775 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
777 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, NULL);
778 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
780 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
781 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
783 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 123, 456);
785 time1 = time2 = 0;
786 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
787 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
788 ok(time1 == 123 && time2 == 456, "Unexpected time values.\n");
790 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 0, 0);
792 time1 = time2 = 1;
793 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
794 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
795 ok(time1 == 0 && time2 == 0, "Unexpected time values.\n");
797 IMFDesiredSample_Clear(desired_sample);
799 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
800 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
802 hr = IMFSample_GetCount(sample, &count);
803 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
804 ok(!count, "Unexpected attribute count %u.\n", count);
806 IMFDesiredSample_Release(desired_sample);
808 hr = IMFSample_GetCount(sample, &count);
809 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
810 ok(!count, "Unexpected attribute count.\n");
812 count = 0;
813 hr = IMFSample_GetBufferCount(sample, &count);
814 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
815 ok(count == 1, "Unexpected attribute count.\n");
817 hr = IMFSample_GetTotalLength(sample, &length);
818 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
819 ok(!length, "Unexpected length %u.\n", length);
821 hr = IMFSample_GetSampleDuration(sample, &duration);
822 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
824 hr = IMFSample_GetSampleTime(sample, &duration);
825 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
827 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
828 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
830 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
831 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
833 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
834 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
835 ok(!length, "Unexpected length %u.\n", length);
837 hr = IMFMediaBuffer_SetCurrentLength(buffer, 16);
838 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
840 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
841 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
842 ok(length == 16, "Unexpected length %u.\n", length);
844 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
845 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
847 hr = IMFMediaBuffer_Unlock(buffer);
848 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
850 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk);
851 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
853 hr = IMFSample_AddBuffer(sample, buffer);
854 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
856 hr = IMFSample_GetBufferCount(sample, &count);
857 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
858 ok(count == 2, "Unexpected attribute count.\n");
860 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
861 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
863 hr = IMFSample_CopyToBuffer(sample, buffer);
864 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
866 hr = IMFSample_RemoveAllBuffers(sample);
867 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
869 hr = IMFSample_GetBufferCount(sample, &count);
870 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
871 ok(!count, "Unexpected attribute count.\n");
873 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
874 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
875 ok(surface == backbuffer, "Unexpected instance.\n");
876 IDirect3DSurface9_Release(surface);
878 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IUnknown, (void **)&surface);
879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
880 ok(surface == backbuffer, "Unexpected instance.\n");
881 IDirect3DSurface9_Release(surface);
883 IMFMediaBuffer_Release(buffer);
885 hr = IMFSample_GetSampleFlags(sample, &flags);
886 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
888 hr = IMFSample_SetSampleFlags(sample, 0x123);
889 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
891 flags = 0;
892 hr = IMFSample_GetSampleFlags(sample, &flags);
893 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
894 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
896 IMFSample_Release(sample);
898 done:
899 if (backbuffer)
900 IDirect3DSurface9_Release(backbuffer);
901 IDirect3D9_Release(d3d);
902 DestroyWindow(window);
905 static void test_default_mixer_type_negotiation(void)
907 IMFMediaType *media_type, *media_type2;
908 IDirect3DDeviceManager9 *manager;
909 DXVA2_VideoProcessorCaps caps;
910 IMFVideoProcessor *processor;
911 IDirect3DDevice9 *device;
912 IMFMediaType *video_type;
913 IMFTransform *transform;
914 GUID guid, *guids;
915 IDirect3D9 *d3d;
916 IUnknown *unk;
917 HWND window;
918 DWORD count;
919 HRESULT hr;
920 UINT token;
922 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
923 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
925 hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
926 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
928 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
929 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
931 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
932 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
934 hr = MFCreateMediaType(&media_type);
935 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
937 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
938 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
940 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
941 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
943 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
944 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
946 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
947 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
949 /* Now try with device manager. */
951 window = create_window();
952 d3d = Direct3DCreate9(D3D_SDK_VERSION);
953 ok(!!d3d, "Failed to create a D3D object.\n");
954 if (!(device = create_device(d3d, window)))
956 skip("Failed to create a D3D device, skipping tests.\n");
957 goto done;
960 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
961 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
963 hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
964 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
966 /* Now manager is not initialized. */
967 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
968 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
970 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
971 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
973 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
974 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
976 /* And now type description is incomplete. */
977 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
978 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
979 IMFMediaType_Release(media_type);
981 video_type = create_video_type(&MFVideoFormat_RGB32);
983 /* Partially initialized type. */
984 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
985 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
987 /* Only required data - frame size and uncompressed marker. */
988 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
989 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
990 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
991 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
993 hr = IMFTransform_SetInputType(transform, 0, video_type, MFT_SET_TYPE_TEST_ONLY);
994 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
996 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
997 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
999 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1000 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1002 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1003 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1004 ok(media_type == video_type, "Unexpected media type instance.\n");
1006 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
1007 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1008 ok(media_type == media_type2, "Unexpected media type instance.\n");
1009 IMFMediaType_Release(media_type);
1010 IMFMediaType_Release(media_type2);
1012 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&processor);
1013 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1015 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1016 todo_wine
1017 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1019 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
1020 todo_wine
1021 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1023 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1024 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1025 ok(media_type == video_type, "Unexpected pointer.\n");
1026 hr = IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&unk);
1027 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1028 IUnknown_Release(unk);
1029 IMFMediaType_Release(media_type);
1031 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1032 todo_wine
1033 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1035 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1036 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1038 hr = IMFTransform_SetOutputType(transform, 1, media_type, 0);
1039 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1041 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
1042 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1044 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1045 todo_wine
1046 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1048 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1049 todo_wine
1050 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1051 if (SUCCEEDED(hr))
1052 CoTaskMemFree(guids);
1054 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
1055 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1056 ok(media_type == media_type2, "Unexpected media type instance.\n");
1057 IMFMediaType_Release(media_type2);
1058 IMFMediaType_Release(media_type);
1060 IMFVideoProcessor_Release(processor);
1062 IMFMediaType_Release(video_type);
1064 IDirect3DDeviceManager9_Release(manager);
1066 IDirect3DDevice9_Release(device);
1068 done:
1069 IMFTransform_Release(transform);
1070 IDirect3D9_Release(d3d);
1071 DestroyWindow(window);
1074 static void test_default_presenter(void)
1076 D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
1077 D3DPRESENT_PARAMETERS present_params = { 0 };
1078 IMFVideoDisplayControl *display_control;
1079 IDirect3DSwapChain9 *swapchain;
1080 IMFVideoPresenter *presenter;
1081 IMFRateSupport *rate_support;
1082 IDirect3DDevice9 *d3d_device;
1083 IDirect3DDeviceManager9 *dm;
1084 IMFVideoDeviceID *deviceid;
1085 IMFGetService *gs;
1086 HWND hwnd, hwnd2;
1087 HANDLE handle;
1088 IUnknown *unk;
1089 DWORD flags;
1090 float rate;
1091 HRESULT hr;
1092 GUID iid;
1094 hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter);
1095 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1097 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1098 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Failed to create default presenter, hr %#x.\n", hr);
1099 if (FAILED(hr))
1100 return;
1102 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
1103 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1105 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
1106 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1108 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
1109 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1110 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
1112 IMFVideoDeviceID_Release(deviceid);
1114 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
1115 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1116 IUnknown_Release(unk);
1118 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&unk);
1119 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1120 IUnknown_Release(unk);
1122 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFGetService, (void **)&gs);
1123 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1125 hr = IMFGetService_GetService(gs, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
1126 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1128 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, NULL);
1129 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1131 flags = 123;
1132 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
1133 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1134 ok(!flags, "Unexpected rendering flags %#x.\n", flags);
1136 IMFVideoDisplayControl_Release(display_control);
1138 hr = IMFGetService_GetService(gs, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1139 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1141 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1142 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1144 hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &handle);
1145 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1147 hr = IDirect3DDeviceManager9_LockDevice(dm, handle, &d3d_device, FALSE);
1148 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1150 hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
1151 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1152 ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
1154 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
1155 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1157 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
1158 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1160 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
1161 ok(present_params.Windowed, "Unexpected windowed mode.\n");
1162 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
1163 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
1164 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
1166 IDirect3DDevice9_Release(d3d_device);
1168 hr = IDirect3DDeviceManager9_UnlockDevice(dm, handle, FALSE);
1169 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1171 /* Video window */
1172 hwnd = create_window();
1173 ok(!!hwnd, "Failed to create a test window.\n");
1175 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, NULL);
1176 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1178 hwnd2 = hwnd;
1179 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1180 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1181 ok(hwnd2 == NULL, "Unexpected window %p.\n", hwnd2);
1183 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, NULL);
1184 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1186 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, (HWND)0x1);
1187 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1189 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1190 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1192 hwnd2 = NULL;
1193 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1194 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1195 ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
1197 /* Video position */
1198 hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, handle);
1199 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1201 IDirect3DDeviceManager9_Release(dm);
1203 IMFVideoDisplayControl_Release(display_control);
1204 IMFGetService_Release(gs);
1206 /* Rate support. */
1207 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
1208 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1210 rate = 1.0f;
1211 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1212 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1213 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1215 rate = 1.0f;
1216 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1217 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1218 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1220 rate = 1.0f;
1221 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1222 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1223 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1225 rate = 1.0f;
1226 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1227 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1228 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1230 IMFRateSupport_Release(rate_support);
1232 IMFVideoPresenter_Release(presenter);
1234 DestroyWindow(hwnd);
1237 static void test_MFCreateVideoMixerAndPresenter(void)
1239 IUnknown *mixer, *presenter;
1240 HRESULT hr;
1242 hr = MFCreateVideoMixerAndPresenter(NULL, NULL, &IID_IUnknown, (void **)&mixer, &IID_IUnknown, (void **)&presenter);
1243 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1245 IUnknown_Release(mixer);
1246 IUnknown_Release(presenter);
1249 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
1250 REFIID riid, void **obj)
1252 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
1253 IsEqualIID(riid, &IID_IUnknown))
1255 *obj = iface;
1256 IMFVideoSampleAllocatorNotify_AddRef(iface);
1257 return S_OK;
1260 *obj = NULL;
1261 return E_NOINTERFACE;
1264 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
1266 return 2;
1269 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
1271 return 1;
1274 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
1276 return E_NOTIMPL;
1279 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
1281 test_notify_callback_QueryInterface,
1282 test_notify_callback_AddRef,
1283 test_notify_callback_Release,
1284 test_notify_callback_NotifyRelease,
1287 static void test_MFCreateVideoSampleAllocator(void)
1289 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
1290 IMFVideoSampleAllocatorCallback *allocator_cb;
1291 IMFMediaType *media_type, *video_type;
1292 IMFVideoSampleAllocator *allocator;
1293 IMFSample *sample, *sample2;
1294 IDirect3DSurface9 *surface;
1295 IMFMediaBuffer *buffer;
1296 IMFGetService *gs;
1297 IUnknown *unk;
1298 HRESULT hr;
1299 LONG count;
1301 hr = MFCreateVideoSampleAllocator(&IID_IUnknown, (void **)&unk);
1302 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1303 IUnknown_Release(unk);
1305 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1306 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1308 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
1309 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1311 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1312 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1314 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
1315 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1317 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1318 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1320 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
1321 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1323 count = 10;
1324 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1325 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1326 ok(!count, "Unexpected count %d.\n", count);
1328 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
1329 todo_wine
1330 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1332 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1333 todo_wine
1334 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1336 hr = MFCreateMediaType(&media_type);
1337 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1339 /* It expects IMFVideoMediaType. */
1340 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
1341 todo_wine
1342 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1344 video_type = create_video_type(&MFVideoFormat_RGB32);
1346 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
1347 todo_wine
1348 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1350 /* Frame size is required. */
1351 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1352 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1353 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1354 todo_wine
1355 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1357 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1358 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1359 todo_wine
1360 ok(count == 1, "Unexpected count %d.\n", count);
1362 sample = NULL;
1363 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1364 todo_wine
1365 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1366 if (SUCCEEDED(hr))
1367 ok(get_refcount(sample) == 3, "Unexpected refcount %u.\n", get_refcount(sample));
1369 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
1370 todo_wine
1371 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
1373 /* Reinitialize with active sample. */
1374 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 4, video_type);
1375 todo_wine
1376 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1377 if (sample)
1378 ok(get_refcount(sample) == 3, "Unexpected refcount %u.\n", get_refcount(sample));
1380 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1381 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1382 todo_wine
1383 ok(count == 4, "Unexpected count %d.\n", count);
1385 if (sample)
1387 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&unk);
1388 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1389 IUnknown_Release(unk);
1391 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
1392 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1393 IUnknown_Release(unk);
1395 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1396 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1398 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
1399 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#x.\n", hr);
1401 /* Device manager wasn't set, sample gets regular memory buffers. */
1402 if (SUCCEEDED(hr))
1404 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1405 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
1406 IMFGetService_Release(gs);
1409 IMFMediaBuffer_Release(buffer);
1411 IMFSample_Release(sample);
1414 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
1416 IMFMediaType_Release(media_type);
1418 IMFVideoSampleAllocator_Release(allocator);
1420 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocatorCallback, (void **)&unk);
1421 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1422 IUnknown_Release(unk);
1425 struct test_host
1427 IMFTopologyServiceLookup IMFTopologyServiceLookup_iface;
1428 IMediaEventSink IMediaEventSink_iface;
1429 IMFTransform *mixer;
1430 IMFVideoPresenter *presenter;
1433 static struct test_host *impl_from_test_host(IMFTopologyServiceLookup *iface)
1435 return CONTAINING_RECORD(iface, struct test_host, IMFTopologyServiceLookup_iface);
1438 static struct test_host *impl_from_test_host_events(IMediaEventSink *iface)
1440 return CONTAINING_RECORD(iface, struct test_host, IMediaEventSink_iface);
1443 static HRESULT WINAPI test_host_QueryInterface(IMFTopologyServiceLookup *iface, REFIID riid, void **obj)
1445 if (IsEqualIID(riid, &IID_IMFTopologyServiceLookup) ||
1446 IsEqualIID(riid, &IID_IUnknown))
1448 *obj = iface;
1449 IMFTopologyServiceLookup_AddRef(iface);
1450 return S_OK;
1453 *obj = NULL;
1454 return E_NOINTERFACE;
1457 static ULONG WINAPI test_host_AddRef(IMFTopologyServiceLookup *iface)
1459 return 2;
1462 static ULONG WINAPI test_host_Release(IMFTopologyServiceLookup *iface)
1464 return 1;
1467 static HRESULT WINAPI test_host_LookupService(IMFTopologyServiceLookup *iface,
1468 MF_SERVICE_LOOKUP_TYPE lookup_type, DWORD index, REFGUID service,
1469 REFIID riid, void **objects, DWORD *num_objects)
1471 struct test_host *host = impl_from_test_host(iface);
1473 ok(*num_objects == 1, "Unexpected number of requested objects %u\n", *num_objects);
1475 memset(objects, 0, *num_objects * sizeof(*objects));
1477 if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
1479 if (IsEqualIID(riid, &IID_IMFClock)) return E_FAIL;
1480 if (IsEqualIID(riid, &IID_IMediaEventSink))
1482 *objects = &host->IMediaEventSink_iface;
1483 IMediaEventSink_AddRef(&host->IMediaEventSink_iface);
1484 return S_OK;
1487 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1488 return E_UNEXPECTED;
1491 if (IsEqualGUID(service, &MR_VIDEO_MIXER_SERVICE))
1493 if (IsEqualIID(riid, &IID_IMFTransform))
1495 *objects = host->mixer;
1496 IMFTransform_AddRef(host->mixer);
1497 return S_OK;
1499 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1500 return E_UNEXPECTED;
1503 return E_NOTIMPL;
1506 static const IMFTopologyServiceLookupVtbl test_host_vtbl =
1508 test_host_QueryInterface,
1509 test_host_AddRef,
1510 test_host_Release,
1511 test_host_LookupService,
1514 static HRESULT WINAPI test_host_events_QueryInterface(IMediaEventSink *iface, REFIID riid, void **obj)
1516 struct test_host *host = impl_from_test_host_events(iface);
1517 return IMFTopologyServiceLookup_QueryInterface(&host->IMFTopologyServiceLookup_iface, riid, obj);
1520 static ULONG WINAPI test_host_events_AddRef(IMediaEventSink *iface)
1522 struct test_host *host = impl_from_test_host_events(iface);
1523 return IMFTopologyServiceLookup_AddRef(&host->IMFTopologyServiceLookup_iface);
1526 static ULONG WINAPI test_host_events_Release(IMediaEventSink *iface)
1528 struct test_host *host = impl_from_test_host_events(iface);
1529 return IMFTopologyServiceLookup_Release(&host->IMFTopologyServiceLookup_iface);
1532 static HRESULT WINAPI test_host_events_Notify(IMediaEventSink *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
1534 return S_OK;
1537 static const IMediaEventSinkVtbl test_host_events_vtbl =
1539 test_host_events_QueryInterface,
1540 test_host_events_AddRef,
1541 test_host_events_Release,
1542 test_host_events_Notify,
1545 static void init_test_host(struct test_host *host, IMFTransform *mixer, IMFVideoPresenter *presenter)
1547 host->IMFTopologyServiceLookup_iface.lpVtbl = &test_host_vtbl;
1548 host->IMediaEventSink_iface.lpVtbl = &test_host_events_vtbl;
1549 /* No need to keep references. */
1550 host->mixer = mixer;
1551 host->presenter = presenter;
1554 static void test_presenter_video_position(void)
1556 IMFTopologyServiceLookupClient *lookup_client;
1557 IMFVideoDisplayControl *display_control;
1558 IMFAttributes *mixer_attributes;
1559 MFVideoNormalizedRect src_rect;
1560 IMFVideoPresenter *presenter;
1561 struct test_host host;
1562 IMFTransform *mixer;
1563 RECT dst_rect;
1564 HRESULT hr;
1565 DWORD count;
1566 HWND hwnd;
1568 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1569 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1571 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1572 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1574 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1575 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1577 init_test_host(&host, mixer, presenter);
1579 /* Clear default mixer attributes, then attach presenter. */
1580 hr = IMFTransform_GetAttributes(mixer, &mixer_attributes);
1581 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1583 hr = IMFAttributes_DeleteAllItems(mixer_attributes);
1584 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1586 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1587 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1589 hr = IMFAttributes_GetCount(mixer_attributes, &count);
1590 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1591 ok(count == 1, "Unexpected count %u.\n", count);
1593 memset(&src_rect, 0, sizeof(src_rect));
1594 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1595 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1596 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1597 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1599 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1600 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1602 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &dst_rect);
1603 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1605 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, NULL);
1606 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1608 SetRect(&dst_rect, 1, 2, 3, 4);
1609 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1610 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1611 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1612 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1613 ok(dst_rect.left == 0 && dst_rect.right == 0 && dst_rect.top == 0 && dst_rect.bottom == 0,
1614 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1616 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, NULL);
1617 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1619 /* Setting position requires a window. */
1620 hwnd = create_window();
1621 ok(!!hwnd, "Failed to create a test window.\n");
1623 SetRect(&dst_rect, 0, 0, 10, 10);
1624 memset(&src_rect, 0, sizeof(src_rect));
1625 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, &dst_rect);
1626 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1628 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1629 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1631 SetRect(&dst_rect, 0, 0, 10, 10);
1632 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1633 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1635 SetRect(&dst_rect, 1, 2, 3, 4);
1636 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1637 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1638 ok(dst_rect.left == 0 && dst_rect.right == 10 && dst_rect.top == 0 && dst_rect.bottom == 10,
1639 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1641 set_rect(&src_rect, 0.0f, 0.0f, 2.0f, 1.0f);
1642 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1643 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1645 set_rect(&src_rect, -0.1f, 0.0f, 0.9f, 1.0f);
1646 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1647 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1649 /* Flipped source rectangle. */
1650 set_rect(&src_rect, 0.5f, 0.0f, 0.4f, 1.0f);
1651 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1652 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1654 set_rect(&src_rect, 0.0f, 0.5f, 0.4f, 0.1f);
1655 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1656 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1658 set_rect(&src_rect, 0.1f, 0.2f, 0.8f, 0.9f);
1659 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1660 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1662 /* Presenter updates mixer attribute. */
1663 memset(&src_rect, 0, sizeof(src_rect));
1664 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1665 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1666 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1667 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1669 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1670 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1671 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1672 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1674 SetRect(&dst_rect, 1, 2, 999, 1000);
1675 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1676 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1678 SetRect(&dst_rect, 0, 1, 3, 4);
1679 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1680 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1681 ok(dst_rect.left == 1 && dst_rect.right == 999 && dst_rect.top == 2 && dst_rect.bottom == 1000,
1682 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1684 /* Flipped destination rectangle. */
1685 SetRect(&dst_rect, 100, 1, 50, 1000);
1686 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1687 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1689 SetRect(&dst_rect, 1, 100, 100, 50);
1690 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1691 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1693 IMFVideoDisplayControl_Release(display_control);
1695 IMFTopologyServiceLookupClient_Release(lookup_client);
1696 IMFVideoPresenter_Release(presenter);
1697 IMFAttributes_Release(mixer_attributes);
1698 IMFTransform_Release(mixer);
1700 DestroyWindow(hwnd);
1703 static void test_presenter_native_video_size(void)
1705 IMFTopologyServiceLookupClient *lookup_client;
1706 IMFVideoDisplayControl *display_control;
1707 IMFVideoPresenter *presenter;
1708 struct test_host host;
1709 IMFTransform *mixer;
1710 SIZE size, ratio;
1711 HRESULT hr;
1712 IMFMediaType *video_type;
1713 IDirect3DDeviceManager9 *dm;
1715 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1716 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1718 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1719 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1721 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1722 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1724 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1727 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, NULL);
1728 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1730 memset(&size, 0xcc, sizeof(size));
1731 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, NULL);
1732 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1733 ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n");
1735 memset(&ratio, 0xcc, sizeof(ratio));
1736 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, &ratio);
1737 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1738 ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n");
1740 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1741 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1743 /* Configure mixer primary stream. */
1744 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1745 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1747 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)dm);
1748 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1750 IDirect3DDeviceManager9_Release(dm);
1752 video_type = create_video_type(&MFVideoFormat_RGB32);
1754 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1755 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1756 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1757 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1759 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1760 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1762 /* Native video size is cached on initialization. */
1763 init_test_host(&host, mixer, presenter);
1765 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1766 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1768 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1769 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1770 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1771 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1772 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1774 /* Update input type. */
1775 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)320 << 32 | 240);
1776 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1778 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1779 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1781 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1782 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1783 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1784 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1785 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1787 /* Negotiating types updates native video size. */
1788 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
1789 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1791 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1792 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1793 ok(size.cx == 320 && size.cy == 240, "Unexpected size %u x %u.\n", size.cx, size.cy);
1794 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1795 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1797 IMFMediaType_Release(video_type);
1798 IMFVideoDisplayControl_Release(display_control);
1799 IMFVideoPresenter_Release(presenter);
1800 IMFTransform_Release(mixer);
1803 static void test_presenter_ar_mode(void)
1805 IMFVideoDisplayControl *display_control;
1806 HRESULT hr;
1807 DWORD mode;
1809 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
1810 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1812 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, NULL);
1813 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1815 mode = 0;
1816 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
1817 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1818 ok(mode == (MFVideoARMode_PreservePicture | MFVideoARMode_PreservePixel), "Unexpected mode %#x.\n", mode);
1820 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, 0x100);
1821 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1823 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_Mask);
1824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1826 mode = 0;
1827 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
1828 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1829 ok(mode == MFVideoARMode_Mask, "Unexpected mode %#x.\n", mode);
1831 IMFVideoDisplayControl_Release(display_control);
1834 static void test_mixer_output_rectangle(void)
1836 IMFVideoMixerControl *mixer_control;
1837 MFVideoNormalizedRect rect;
1838 IMFTransform *mixer;
1839 HRESULT hr;
1841 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1842 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1844 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
1845 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1847 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, NULL);
1848 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1850 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
1851 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, &rect);
1852 ok(hr == S_OK, "Failed to get output rect, hr %#x.\n", hr);
1853 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
1854 "Unexpected rectangle.\n");
1856 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, &rect);
1857 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1859 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, NULL);
1860 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1862 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, &rect);
1863 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1865 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, NULL);
1866 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1868 /* Wrong bounds. */
1869 set_rect(&rect, 0.0f, 0.0f, 1.1f, 1.0f);
1870 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
1871 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1873 set_rect(&rect, -0.1f, 0.0f, 0.5f, 1.0f);
1874 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
1875 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1877 /* Flipped. */
1878 set_rect(&rect, 1.0f, 0.0f, 0.0f, 1.0f);
1879 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
1880 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1882 set_rect(&rect, 0.0f, 1.0f, 1.0f, 0.5f);
1883 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
1884 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1886 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, NULL);
1887 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1889 IMFVideoMixerControl_Release(mixer_control);
1890 IMFTransform_Release(mixer);
1893 static void test_mixer_zorder(void)
1895 IMFVideoMixerControl *mixer_control;
1896 IMFTransform *mixer;
1897 DWORD ids[2];
1898 DWORD value;
1899 HRESULT hr;
1901 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1902 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1904 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
1905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1907 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, NULL);
1908 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1910 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, NULL);
1911 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1913 value = 1;
1914 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, &value);
1915 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1916 ok(!value, "Unexpected value %u.\n", value);
1918 value = 1;
1919 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
1920 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1922 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 1);
1923 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1925 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 1);
1926 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1928 /* Exceeds maximum stream number. */
1929 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 20);
1930 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1932 value = 1;
1933 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
1934 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1936 value = 0;
1937 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
1938 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1939 ok(value == 1, "Unexpected zorder %u.\n", value);
1941 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 0);
1942 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1944 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 2);
1945 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1947 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 0);
1948 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1950 value = 2;
1951 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
1952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1954 value = 0;
1955 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
1956 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1957 ok(value == 2, "Unexpected zorder %u.\n", value);
1959 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 2, 1);
1960 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1962 value = 3;
1963 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
1964 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1966 value = 0;
1967 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 3, &value);
1968 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1969 ok(value == 3, "Unexpected zorder %u.\n", value);
1971 hr = IMFTransform_DeleteInputStream(mixer, 1);
1972 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1973 hr = IMFTransform_DeleteInputStream(mixer, 2);
1974 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1975 hr = IMFTransform_DeleteInputStream(mixer, 3);
1976 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1978 ids[0] = 2;
1979 ids[1] = 1;
1980 hr = IMFTransform_AddInputStreams(mixer, 2, ids);
1981 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1983 value = 0;
1984 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
1985 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1986 ok(value == 2, "Unexpected zorder %u.\n", value);
1988 value = 0;
1989 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
1990 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1991 ok(value == 1, "Unexpected zorder %u.\n", value);
1993 IMFVideoMixerControl_Release(mixer_control);
1994 IMFTransform_Release(mixer);
1997 static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, unsigned int width,
1998 unsigned int height)
2000 IDirectXVideoAccelerationService *service;
2001 IDirect3DSurface9 *surface = NULL;
2002 IDirect3DDevice9 *device;
2003 HANDLE handle;
2004 HRESULT hr;
2006 hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle);
2007 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2009 hr = IDirect3DDeviceManager9_LockDevice(manager, handle, &device, TRUE);
2010 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2012 hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
2013 (void **)&service);
2014 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2016 hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, D3DFMT_A8R8G8B8,
2017 D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &surface, NULL);
2018 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2020 IDirectXVideoAccelerationService_Release(service);
2022 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00));
2023 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2025 IDirect3DDevice9_Release(device);
2027 hr = IDirect3DDeviceManager9_UnlockDevice(manager, handle, FALSE);
2028 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2030 hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
2031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2033 return surface;
2036 /* Format is assumed as 32bpp */
2037 static DWORD get_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
2039 D3DLOCKED_RECT locked_rect = { 0 };
2040 D3DSURFACE_DESC desc;
2041 DWORD *row, color;
2042 HRESULT hr;
2044 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2045 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2046 ok(x < desc.Width && y < desc.Height, "Invalid coordinate.\n");
2047 if (x >= desc.Width || y >= desc.Height) return 0;
2049 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2050 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2052 row = (DWORD *)((char *)locked_rect.pBits + y * locked_rect.Pitch);
2053 color = row[x];
2055 hr = IDirect3DSurface9_UnlockRect(surface);
2056 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2058 return color;
2061 static void test_mixer_samples(void)
2063 IDirect3DDeviceManager9 *manager;
2064 MFT_OUTPUT_DATA_BUFFER buffer;
2065 IDirect3DSurface9 *surface;
2066 IMFDesiredSample *desired;
2067 IDirect3DDevice9 *device;
2068 IMFMediaType *video_type;
2069 DWORD color, status;
2070 IMFTransform *mixer;
2071 IMFSample *sample;
2072 IDirect3D9 *d3d;
2073 HWND window;
2074 UINT token;
2075 HRESULT hr;
2077 window = create_window();
2078 d3d = Direct3DCreate9(D3D_SDK_VERSION);
2079 ok(!!d3d, "Failed to create a D3D object.\n");
2080 if (!(device = create_device(d3d, window)))
2082 skip("Failed to create a D3D device, skipping tests.\n");
2083 goto done;
2086 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2087 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2089 hr = IMFTransform_GetInputStatus(mixer, 0, NULL);
2090 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2092 hr = IMFTransform_GetInputStatus(mixer, 1, NULL);
2093 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2095 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2096 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2098 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2099 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2101 hr = IMFTransform_GetOutputStatus(mixer, NULL);
2102 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2104 hr = IMFTransform_GetOutputStatus(mixer, &status);
2105 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2107 /* Configure device and media types. */
2108 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2109 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2111 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2112 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
2114 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2115 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2117 video_type = create_video_type(&MFVideoFormat_RGB32);
2119 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
2120 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2121 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2122 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2124 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
2125 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2127 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2128 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2130 hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0);
2131 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2133 status = 0;
2134 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2135 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2136 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2138 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2139 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2141 status = ~0u;
2142 hr = IMFTransform_GetOutputStatus(mixer, &status);
2143 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2144 ok(!status, "Unexpected status %#x.\n", status);
2146 IMFMediaType_Release(video_type);
2148 memset(&buffer, 0, sizeof(buffer));
2149 hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
2150 todo_wine
2151 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2153 /* It needs a sample with a backing surface. */
2154 hr = MFCreateSample(&sample);
2155 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2157 buffer.pSample = sample;
2158 hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
2159 todo_wine
2160 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2162 IMFSample_Release(sample);
2164 surface = create_surface(manager, 64, 64);
2166 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
2167 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2169 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired);
2170 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2172 buffer.pSample = sample;
2173 hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
2174 todo_wine
2175 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2177 color = get_surface_color(surface, 0, 0);
2178 ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#x.\n", color);
2180 /* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
2181 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
2183 hr = IMFTransform_ProcessOutput(mixer, 0, 1, &buffer, &status);
2184 todo_wine
2185 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2187 color = get_surface_color(surface, 0, 0);
2188 todo_wine
2189 ok(!color, "Unexpected color %#x.\n", color);
2191 IMFDesiredSample_Clear(desired);
2193 hr = IMFTransform_ProcessInput(mixer, 0, NULL, 0);
2194 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2196 hr = IMFTransform_ProcessInput(mixer, 5, NULL, 0);
2197 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2199 status = 0;
2200 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2201 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2202 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2204 status = ~0u;
2205 hr = IMFTransform_GetOutputStatus(mixer, &status);
2206 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2207 ok(!status, "Unexpected status %#x.\n", status);
2209 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2210 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2212 status = ~0u;
2213 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2215 ok(!status, "Unexpected status %#x.\n", status);
2217 hr = IMFTransform_GetOutputStatus(mixer, &status);
2218 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2219 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#x.\n", status);
2221 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2222 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
2224 hr = IMFTransform_ProcessInput(mixer, 5, sample, 0);
2225 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2227 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_DRAIN, 0);
2228 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2230 IMFSample_Release(sample);
2232 IDirect3DSurface9_Release(surface);
2234 IMFTransform_Release(mixer);
2236 IDirect3DDevice9_Release(device);
2237 IDirect3DDeviceManager9_Release(manager);
2239 done:
2240 IDirect3D9_Release(d3d);
2241 DestroyWindow(window);
2244 START_TEST(evr)
2246 CoInitialize(NULL);
2248 test_aggregation();
2249 test_interfaces();
2250 test_enum_pins();
2251 test_find_pin();
2252 test_pin_info();
2253 test_default_mixer();
2254 test_default_mixer_type_negotiation();
2255 test_surface_sample();
2256 test_default_presenter();
2257 test_MFCreateVideoMixerAndPresenter();
2258 test_MFCreateVideoSampleAllocator();
2259 test_presenter_video_position();
2260 test_presenter_native_video_size();
2261 test_presenter_ar_mode();
2262 test_mixer_output_rectangle();
2263 test_mixer_zorder();
2264 test_mixer_samples();
2266 CoUninitialize();