evr/presenter: Handle shutdown state in more methods.
[wine.git] / dlls / evr / tests / evr.c
blob6a711e30581959222ada7e4c000712de066b7230
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(HWND focus_window)
54 D3DPRESENT_PARAMETERS present_parameters = {0};
55 IDirect3DDevice9 *device = NULL;
56 IDirect3D9 *d3d9;
58 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
59 ok(!!d3d9, "Failed to create a D3D object.\n");
61 present_parameters.BackBufferWidth = 640;
62 present_parameters.BackBufferHeight = 480;
63 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
64 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
65 present_parameters.hDeviceWindow = focus_window;
66 present_parameters.Windowed = TRUE;
67 present_parameters.EnableAutoDepthStencil = TRUE;
68 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
70 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
71 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
73 IDirect3D9_Release(d3d9);
75 return device;
78 static IBaseFilter *create_evr(void)
80 IBaseFilter *filter = NULL;
81 HRESULT hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC_SERVER,
82 &IID_IBaseFilter, (void **)&filter);
83 ok(hr == S_OK, "Got hr %#x.\n", hr);
84 return filter;
87 static ULONG get_refcount(void *iface)
89 IUnknown *unknown = iface;
90 IUnknown_AddRef(unknown);
91 return IUnknown_Release(unknown);
94 static const GUID test_iid = {0x33333333};
95 static LONG outer_ref = 1;
97 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
99 if (IsEqualGUID(iid, &IID_IUnknown)
100 || IsEqualGUID(iid, &IID_IBaseFilter)
101 || IsEqualGUID(iid, &test_iid))
103 *out = (IUnknown *)0xdeadbeef;
104 return S_OK;
106 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
107 return E_NOINTERFACE;
110 static ULONG WINAPI outer_AddRef(IUnknown *iface)
112 return InterlockedIncrement(&outer_ref);
115 static ULONG WINAPI outer_Release(IUnknown *iface)
117 return InterlockedDecrement(&outer_ref);
120 static const IUnknownVtbl outer_vtbl =
122 outer_QueryInterface,
123 outer_AddRef,
124 outer_Release,
127 static IUnknown test_outer = {&outer_vtbl};
129 static void test_aggregation(void)
131 IBaseFilter *filter, *filter2;
132 IMFVideoPresenter *presenter;
133 IUnknown *unk, *unk2;
134 IMFTransform *mixer;
135 HRESULT hr;
136 ULONG ref;
138 filter = (IBaseFilter *)0xdeadbeef;
139 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
140 &IID_IBaseFilter, (void **)&filter);
141 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
142 ok(!filter, "Got interface %p.\n", filter);
144 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
145 &IID_IUnknown, (void **)&unk);
146 ok(hr == S_OK, "Got hr %#x.\n", hr);
147 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
148 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
149 ref = get_refcount(unk);
150 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
152 ref = IUnknown_AddRef(unk);
153 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
154 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
156 ref = IUnknown_Release(unk);
157 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
158 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
160 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
161 ok(hr == S_OK, "Got hr %#x.\n", hr);
162 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
163 IUnknown_Release(unk2);
165 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
166 ok(hr == S_OK, "Got hr %#x.\n", hr);
168 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
169 ok(hr == S_OK, "Got hr %#x.\n", hr);
170 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
172 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
173 ok(hr == S_OK, "Got hr %#x.\n", hr);
174 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
176 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
177 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
178 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
180 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
181 ok(hr == S_OK, "Got hr %#x.\n", hr);
182 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
184 IBaseFilter_Release(filter);
185 ref = IUnknown_Release(unk);
186 ok(!ref, "Got unexpected refcount %d.\n", ref);
187 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
189 /* Default presenter. */
190 presenter = (void *)0xdeadbeef;
191 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter,
192 (void **)&presenter);
193 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
194 ok(!presenter, "Got interface %p.\n", presenter);
196 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
197 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Unexpected hr %#x.\n", hr);
198 if (SUCCEEDED(hr))
200 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
201 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
202 ref = get_refcount(unk);
203 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
205 IUnknown_Release(unk);
208 /* Default mixer. */
209 presenter = (void *)0xdeadbeef;
210 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
211 (void **)&mixer);
212 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
213 ok(!mixer, "Got interface %p.\n", mixer);
215 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
216 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
217 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
218 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
219 ref = get_refcount(unk);
220 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
222 IUnknown_Release(unk);
225 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
226 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
228 IUnknown *iface = iface_ptr;
229 HRESULT hr, expected_hr;
230 IUnknown *unk;
232 expected_hr = supported ? S_OK : E_NOINTERFACE;
234 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
235 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
236 if (SUCCEEDED(hr))
237 IUnknown_Release(unk);
240 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
241 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
243 IUnknown *iface = iface_ptr;
244 HRESULT hr, expected_hr;
245 IUnknown *unk;
247 expected_hr = supported ? S_OK : E_NOINTERFACE;
249 hr = MFGetService(iface, service, iid, (void **)&unk);
250 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
251 if (SUCCEEDED(hr))
252 IUnknown_Release(unk);
255 static void test_interfaces(void)
257 IBaseFilter *filter = create_evr();
258 ULONG ref;
260 todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
261 check_interface(filter, &IID_IBaseFilter, TRUE);
262 check_interface(filter, &IID_IEVRFilterConfig, TRUE);
263 check_interface(filter, &IID_IMediaFilter, TRUE);
264 check_interface(filter, &IID_IMediaPosition, TRUE);
265 check_interface(filter, &IID_IMediaSeeking, TRUE);
266 check_interface(filter, &IID_IPersist, TRUE);
267 check_interface(filter, &IID_IUnknown, TRUE);
269 check_interface(filter, &IID_IBasicAudio, FALSE);
270 check_interface(filter, &IID_IBasicVideo, FALSE);
271 check_interface(filter, &IID_IDirectXVideoMemoryConfiguration, FALSE);
272 check_interface(filter, &IID_IMemInputPin, FALSE);
273 check_interface(filter, &IID_IPersistPropertyBag, FALSE);
274 check_interface(filter, &IID_IPin, FALSE);
275 check_interface(filter, &IID_IReferenceClock, FALSE);
276 check_interface(filter, &IID_IVideoWindow, FALSE);
278 ref = IBaseFilter_Release(filter);
279 ok(!ref, "Got unexpected refcount %d.\n", ref);
282 static void test_enum_pins(void)
284 IBaseFilter *filter = create_evr();
285 IEnumPins *enum1, *enum2;
286 ULONG count, ref;
287 IPin *pins[2];
288 HRESULT hr;
290 ref = get_refcount(filter);
291 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
293 hr = IBaseFilter_EnumPins(filter, NULL);
294 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
296 hr = IBaseFilter_EnumPins(filter, &enum1);
297 ok(hr == S_OK, "Got hr %#x.\n", hr);
298 ref = get_refcount(filter);
299 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
300 ref = get_refcount(enum1);
301 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
303 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
304 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
306 hr = IEnumPins_Next(enum1, 1, pins, NULL);
307 ok(hr == S_OK, "Got hr %#x.\n", hr);
308 ref = get_refcount(filter);
309 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
310 ref = get_refcount(pins[0]);
311 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
312 ref = get_refcount(enum1);
313 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
314 IPin_Release(pins[0]);
315 ref = get_refcount(filter);
316 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
318 hr = IEnumPins_Next(enum1, 1, pins, NULL);
319 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
321 hr = IEnumPins_Reset(enum1);
322 ok(hr == S_OK, "Got hr %#x.\n", hr);
324 hr = IEnumPins_Next(enum1, 1, pins, &count);
325 ok(hr == S_OK, "Got hr %#x.\n", hr);
326 ok(count == 1, "Got count %u.\n", count);
327 IPin_Release(pins[0]);
329 hr = IEnumPins_Next(enum1, 1, pins, &count);
330 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
331 ok(!count, "Got count %u.\n", count);
333 hr = IEnumPins_Reset(enum1);
334 ok(hr == S_OK, "Got hr %#x.\n", hr);
336 hr = IEnumPins_Next(enum1, 2, pins, NULL);
337 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
339 hr = IEnumPins_Next(enum1, 2, pins, &count);
340 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
341 ok(count == 1, "Got count %u.\n", count);
342 IPin_Release(pins[0]);
344 hr = IEnumPins_Reset(enum1);
345 ok(hr == S_OK, "Got hr %#x.\n", hr);
347 hr = IEnumPins_Clone(enum1, &enum2);
348 ok(hr == S_OK, "Got hr %#x.\n", hr);
350 hr = IEnumPins_Skip(enum1, 2);
351 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
353 hr = IEnumPins_Skip(enum1, 1);
354 ok(hr == S_OK, "Got hr %#x.\n", hr);
356 hr = IEnumPins_Skip(enum1, 1);
357 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
359 hr = IEnumPins_Next(enum1, 1, pins, NULL);
360 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
362 hr = IEnumPins_Next(enum2, 1, pins, NULL);
363 ok(hr == S_OK, "Got hr %#x.\n", hr);
364 IPin_Release(pins[0]);
366 IEnumPins_Release(enum2);
367 IEnumPins_Release(enum1);
368 ref = IBaseFilter_Release(filter);
369 ok(!ref, "Got outstanding refcount %d.\n", ref);
372 static void test_find_pin(void)
374 IBaseFilter *filter = create_evr();
375 IEnumPins *enum_pins;
376 IPin *pin, *pin2;
377 HRESULT hr;
378 ULONG ref;
380 hr = IBaseFilter_EnumPins(filter, &enum_pins);
381 ok(hr == S_OK, "Got hr %#x.\n", hr);
383 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
384 ok(hr == S_OK, "Got hr %#x.\n", hr);
385 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
386 ok(hr == S_OK, "Got hr %#x.\n", hr);
387 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
388 IPin_Release(pin2);
389 IPin_Release(pin);
391 IEnumPins_Release(enum_pins);
392 ref = IBaseFilter_Release(filter);
393 ok(!ref, "Got outstanding refcount %d.\n", ref);
396 static void test_pin_info(void)
398 IBaseFilter *filter = create_evr();
399 PIN_DIRECTION dir;
400 PIN_INFO info;
401 HRESULT hr;
402 WCHAR *id;
403 ULONG ref;
404 IPin *pin;
406 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
407 ok(hr == S_OK, "Got hr %#x.\n", hr);
408 ref = get_refcount(filter);
409 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
410 ref = get_refcount(pin);
411 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
413 hr = IPin_QueryPinInfo(pin, &info);
414 ok(hr == S_OK, "Got hr %#x.\n", hr);
415 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
416 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
417 ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
418 ref = get_refcount(filter);
419 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
420 ref = get_refcount(pin);
421 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
422 IBaseFilter_Release(info.pFilter);
424 hr = IPin_QueryDirection(pin, &dir);
425 ok(hr == S_OK, "Got hr %#x.\n", hr);
426 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
428 hr = IPin_QueryId(pin, &id);
429 ok(hr == S_OK, "Got hr %#x.\n", hr);
430 ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
431 CoTaskMemFree(id);
433 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
434 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
436 IPin_Release(pin);
437 ref = IBaseFilter_Release(filter);
438 ok(!ref, "Got outstanding refcount %d.\n", ref);
441 static IMFMediaType * create_video_type(const GUID *subtype)
443 IMFMediaType *video_type;
444 HRESULT hr;
446 hr = MFCreateMediaType(&video_type);
447 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
449 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
450 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
452 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
453 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
455 return video_type;
458 static void test_default_mixer(void)
460 DWORD input_min, input_max, output_min, output_max;
461 IMFAttributes *attributes, *attributes2;
462 IMFVideoMixerControl2 *mixer_control2;
463 MFT_OUTPUT_STREAM_INFO output_info;
464 MFT_INPUT_STREAM_INFO input_info;
465 DWORD input_count, output_count;
466 IMFVideoProcessor *processor;
467 IMFVideoDeviceID *deviceid;
468 MFVideoNormalizedRect rect;
469 DWORD input_id, output_id;
470 IMFTransform *transform;
471 DXVA2_ValueRange range;
472 DXVA2_Fixed32 dxva_value;
473 DWORD flags, value, count;
474 COLORREF color;
475 unsigned int i;
476 DWORD ids[16];
477 IUnknown *unk;
478 GUID *guids;
479 HRESULT hr;
480 IID iid;
482 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
483 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
485 check_interface(transform, &IID_IMFQualityAdvise, TRUE);
486 check_interface(transform, &IID_IMFClockStateSink, TRUE);
487 check_interface(transform, &IID_IMFTopologyServiceLookupClient, TRUE);
488 check_interface(transform, &IID_IMFGetService, TRUE);
489 check_interface(transform, &IID_IMFAttributes, TRUE);
490 check_interface(transform, &IID_IMFVideoMixerBitmap, TRUE);
491 check_interface(transform, &IID_IMFVideoPositionMapper, TRUE);
492 check_interface(transform, &IID_IMFVideoProcessor, TRUE);
493 check_interface(transform, &IID_IMFVideoMixerControl, TRUE);
494 check_interface(transform, &IID_IMFVideoDeviceID, TRUE);
495 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerBitmap, TRUE);
496 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, TRUE);
497 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, TRUE);
498 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
499 check_service_interface(transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFTransform, FALSE);
501 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_RENDER_SERVICE, &IID_IUnknown, (void **)&unk);
502 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#x.\n", hr);
504 if (SUCCEEDED(MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl2, (void **)&mixer_control2)))
506 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, NULL);
507 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
509 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, &flags);
510 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
511 ok(!flags, "Unexpected flags %#x.\n", flags);
513 IMFVideoMixerControl2_Release(mixer_control2);
516 hr = MFGetService((IUnknown *)transform, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, (void **)&processor);
517 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
519 hr = IMFVideoProcessor_GetBackgroundColor(processor, NULL);
520 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
522 color = 1;
523 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
524 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
525 ok(!color, "Unexpected color %#x.\n", color);
527 hr = IMFVideoProcessor_SetBackgroundColor(processor, 0x00121212);
528 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
530 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
531 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
532 ok(color == 0x121212, "Unexpected color %#x.\n", color);
534 hr = IMFVideoProcessor_GetFilteringRange(processor, DXVA2_DetailFilterChromaLevel, &range);
535 todo_wine
536 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
538 hr = IMFVideoProcessor_GetFilteringValue(processor, DXVA2_DetailFilterChromaLevel, &dxva_value);
539 todo_wine
540 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
542 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
543 todo_wine
544 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
546 IMFVideoProcessor_Release(processor);
548 hr = IMFTransform_SetOutputBounds(transform, 100, 10);
549 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
551 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid);
552 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
554 hr = IMFTransform_GetAttributes(transform, NULL);
555 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
557 hr = IMFTransform_GetAttributes(transform, &attributes);
558 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
560 hr = IMFTransform_GetAttributes(transform, &attributes2);
561 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
562 ok(attributes == attributes2, "Unexpected attributes instance.\n");
563 IMFAttributes_Release(attributes2);
565 hr = IMFTransform_QueryInterface(transform, &IID_IMFAttributes, (void **)&attributes2);
566 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
567 ok(attributes != attributes2, "Unexpected attributes instance.\n");
569 hr = IMFAttributes_QueryInterface(attributes2, &IID_IMFTransform, (void **)&unk);
570 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
571 IUnknown_Release(unk);
573 hr = IMFAttributes_GetCount(attributes2, &count);
574 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
575 ok(count == 1, "Unexpected attribute count %u.\n", count);
577 value = 0;
578 hr = IMFAttributes_GetUINT32(attributes2, &MF_SA_D3D_AWARE, &value);
579 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
580 ok(value == 1, "Unexpected value %d.\n", value);
582 IMFAttributes_Release(attributes2);
584 hr = IMFAttributes_GetCount(attributes, &count);
585 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
586 ok(count == 1, "Unexpected attribute count %u.\n", count);
588 memset(&rect, 0, sizeof(rect));
589 hr = IMFAttributes_GetBlob(attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&rect, sizeof(rect), NULL);
590 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
591 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
592 "Unexpected zoom rect (%f, %f) - (%f, %f).\n", rect.left, rect.top, rect.right, rect.bottom);
594 IMFAttributes_Release(attributes);
596 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
597 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
599 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
600 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
601 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
603 IMFVideoDeviceID_Release(deviceid);
605 /* Stream configuration. */
606 input_count = output_count = 0;
607 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
608 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
609 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
611 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
612 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
613 ok(input_min == 1 && input_max == 16 && output_min == 1 && output_max == 1, "Unexpected stream limits %u/%u, %u/%u.\n",
614 input_min, input_max, output_min, output_max);
616 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
617 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
619 hr = IMFTransform_GetOutputStreamInfo(transform, 1, &output_info);
620 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
622 memset(&input_info, 0xcc, sizeof(input_info));
623 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
624 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
626 memset(&output_info, 0xcc, sizeof(output_info));
627 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
628 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
629 ok(!(output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)),
630 "Unexpected output flags %#x.\n", output_info.dwFlags);
632 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
633 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
634 ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
636 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
637 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
639 hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
640 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
642 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
643 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
645 hr = IMFTransform_AddInputStreams(transform, 16, NULL);
646 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
648 hr = IMFTransform_AddInputStreams(transform, 16, ids);
649 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
651 memset(ids, 0, sizeof(ids));
652 hr = IMFTransform_AddInputStreams(transform, 15, ids);
653 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
655 for (i = 0; i < ARRAY_SIZE(ids); ++i)
656 ids[i] = i + 1;
658 hr = IMFTransform_AddInputStreams(transform, 15, ids);
659 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
661 input_count = output_count = 0;
662 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
663 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
664 ok(input_count == 16 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
666 memset(&input_info, 0, sizeof(input_info));
667 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
668 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
669 ok((input_info.dwFlags & (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL)) ==
670 (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL), "Unexpected flags %#x.\n", input_info.dwFlags);
672 attributes = NULL;
673 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
674 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
675 hr = IMFAttributes_GetCount(attributes, &count);
676 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
677 ok(count == 1, "Unexpected count %u.\n", count);
678 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &count);
679 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
680 ok(count == 1, "Unexpected count %u.\n", count);
681 ok(!!attributes, "Unexpected attributes.\n");
683 attributes2 = NULL;
684 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
685 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
686 ok(attributes == attributes2, "Unexpected instance.\n");
688 IMFAttributes_Release(attributes2);
689 IMFAttributes_Release(attributes);
691 attributes = NULL;
692 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
693 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
694 ok(!!attributes, "Unexpected attributes.\n");
695 IMFAttributes_Release(attributes);
697 hr = IMFTransform_DeleteInputStream(transform, 0);
698 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
700 hr = IMFTransform_DeleteInputStream(transform, 1);
701 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
703 input_count = output_count = 0;
704 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
705 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
706 ok(input_count == 15 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
708 IMFTransform_Release(transform);
710 hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
711 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
713 hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
714 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
715 IMFTransform_Release(transform);
718 static void test_surface_sample(void)
720 IDirect3DSurface9 *backbuffer = NULL, *surface;
721 IMFDesiredSample *desired_sample;
722 IMFMediaBuffer *buffer, *buffer2;
723 LONGLONG duration, time1, time2;
724 IDirect3DSwapChain9 *swapchain;
725 DWORD flags, count, length;
726 IDirect3DDevice9 *device;
727 IMFSample *sample;
728 IUnknown *unk;
729 HWND window;
730 HRESULT hr;
731 BYTE *data;
733 window = create_window();
734 if (!(device = create_device(window)))
736 skip("Failed to create a D3D device, skipping tests.\n");
737 goto done;
740 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
741 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
743 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
744 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
745 ok(backbuffer != NULL, "The back buffer is NULL\n");
747 IDirect3DSwapChain9_Release(swapchain);
749 hr = MFCreateVideoSampleFromSurface(NULL, &sample);
750 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
751 IMFSample_Release(sample);
753 hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample);
754 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
756 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
757 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
758 IUnknown_Release(unk);
760 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired_sample);
761 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
763 hr = IMFSample_GetCount(sample, &count);
764 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
765 ok(!count, "Unexpected attribute count %u.\n", count);
767 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, NULL);
768 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
770 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, NULL, &time2);
771 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
773 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, NULL);
774 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
776 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
777 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
779 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 123, 456);
781 time1 = time2 = 0;
782 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
783 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
784 ok(time1 == 123 && time2 == 456, "Unexpected time values.\n");
786 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 0, 0);
788 time1 = time2 = 1;
789 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
790 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
791 ok(time1 == 0 && time2 == 0, "Unexpected time values.\n");
793 IMFDesiredSample_Clear(desired_sample);
795 hr = IMFDesiredSample_GetDesiredSampleTimeAndDuration(desired_sample, &time1, &time2);
796 ok(hr == MF_E_NOT_AVAILABLE, "Unexpected hr %#x.\n", hr);
798 hr = IMFSample_GetCount(sample, &count);
799 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
800 ok(!count, "Unexpected attribute count %u.\n", count);
802 /* Attributes are cleared. */
803 hr = IMFSample_SetUnknown(sample, &MFSampleExtension_Token, NULL);
804 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
806 hr = IMFSample_GetCount(sample, &count);
807 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
808 ok(count == 1, "Unexpected attribute count %u.\n", count);
810 hr = IMFSample_SetSampleTime(sample, 0);
811 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
813 hr = IMFSample_GetSampleTime(sample, &time1);
814 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
816 hr = IMFSample_SetSampleDuration(sample, 0);
817 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
819 hr = IMFSample_GetSampleDuration(sample, &duration);
820 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
822 hr = IMFSample_SetSampleFlags(sample, 0x1);
823 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
825 IMFDesiredSample_Clear(desired_sample);
827 hr = IMFSample_GetCount(sample, &count);
828 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
829 ok(!count, "Unexpected attribute count %u.\n", count);
831 hr = IMFSample_GetSampleTime(sample, &time1);
832 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
834 hr = IMFSample_GetSampleDuration(sample, &duration);
835 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
837 hr = IMFSample_GetSampleFlags(sample, &flags);
838 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
839 ok(flags == 0, "Unexpected flags %#x.\n", flags);
841 IMFDesiredSample_Release(desired_sample);
843 hr = IMFSample_GetCount(sample, &count);
844 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
845 ok(!count, "Unexpected attribute count.\n");
847 count = 0;
848 hr = IMFSample_GetBufferCount(sample, &count);
849 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
850 ok(count == 1, "Unexpected attribute count.\n");
852 hr = IMFSample_GetTotalLength(sample, &length);
853 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
854 ok(!length, "Unexpected length %u.\n", length);
856 hr = IMFSample_GetSampleDuration(sample, &duration);
857 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
859 hr = IMFSample_GetSampleTime(sample, &duration);
860 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
862 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
863 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
865 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
866 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
868 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
869 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
870 ok(!length, "Unexpected length %u.\n", length);
872 hr = IMFMediaBuffer_SetCurrentLength(buffer, 16);
873 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
875 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
876 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
877 ok(length == 16, "Unexpected length %u.\n", length);
879 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
880 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
882 hr = IMFMediaBuffer_Unlock(buffer);
883 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
885 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk);
886 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
888 hr = IMFSample_AddBuffer(sample, buffer);
889 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
891 hr = IMFSample_GetBufferCount(sample, &count);
892 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
893 ok(count == 2, "Unexpected attribute count.\n");
895 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
896 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
898 hr = IMFSample_CopyToBuffer(sample, buffer);
899 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
901 hr = IMFSample_RemoveAllBuffers(sample);
902 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
904 hr = IMFSample_GetBufferCount(sample, &count);
905 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
906 ok(!count, "Unexpected attribute count.\n");
908 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
909 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
910 ok(surface == backbuffer, "Unexpected instance.\n");
911 IDirect3DSurface9_Release(surface);
913 hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IUnknown, (void **)&surface);
914 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
915 ok(surface == backbuffer, "Unexpected instance.\n");
916 IDirect3DSurface9_Release(surface);
918 IMFMediaBuffer_Release(buffer);
920 hr = IMFSample_GetSampleFlags(sample, &flags);
921 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
923 hr = IMFSample_SetSampleFlags(sample, 0x123);
924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
926 flags = 0;
927 hr = IMFSample_GetSampleFlags(sample, &flags);
928 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
929 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
931 IMFSample_Release(sample);
933 done:
934 if (backbuffer)
935 IDirect3DSurface9_Release(backbuffer);
936 DestroyWindow(window);
939 static void test_default_mixer_type_negotiation(void)
941 IMFMediaType *media_type, *media_type2;
942 IDirect3DDeviceManager9 *manager;
943 DXVA2_VideoProcessorCaps caps;
944 IMFVideoProcessor *processor;
945 GUID subtype, guid, *guids;
946 IDirect3DDevice9 *device;
947 IMFMediaType *video_type;
948 IMFTransform *transform;
949 MFVideoArea aperture;
950 DWORD index, count;
951 IUnknown *unk;
952 HWND window;
953 HRESULT hr;
954 UINT token;
956 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
957 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
959 hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
960 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
962 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
963 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
965 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
966 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
968 hr = MFCreateMediaType(&media_type);
969 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
971 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
972 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
974 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
975 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
977 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
978 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
980 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
981 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
983 /* Now try with device manager. */
985 window = create_window();
986 if (!(device = create_device(window)))
988 skip("Failed to create a D3D device, skipping tests.\n");
989 goto done;
992 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
993 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
995 hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
996 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
998 /* Now manager is not initialized. */
999 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1000 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1002 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
1003 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1005 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1006 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1008 /* And now type description is incomplete. */
1009 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
1010 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1011 IMFMediaType_Release(media_type);
1013 video_type = create_video_type(&MFVideoFormat_RGB32);
1015 /* Partially initialized type. */
1016 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1017 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1019 /* Only required data - frame size and uncompressed marker. */
1020 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1021 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1022 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1023 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1024 memset(&aperture, 0, sizeof(aperture));
1025 aperture.Area.cx = 100; aperture.Area.cy = 200;
1026 hr = IMFMediaType_SetBlob(video_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture));
1027 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1028 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, 2);
1029 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1031 hr = IMFTransform_SetInputType(transform, 0, video_type, MFT_SET_TYPE_TEST_ONLY);
1032 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1034 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1035 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1037 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1038 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1040 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1041 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1043 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1044 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1045 ok(media_type == video_type, "Unexpected media type instance.\n");
1047 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
1048 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1049 ok(media_type == media_type2, "Unexpected media type instance.\n");
1050 IMFMediaType_Release(media_type);
1051 IMFMediaType_Release(media_type2);
1053 /* Modified after type was set. */
1054 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, (UINT64)56 << 32 | 55);
1055 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1057 /* Check attributes on available output types. */
1058 index = 0;
1059 while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
1061 UINT64 frame_size, ratio;
1062 MFVideoArea aperture;
1063 GUID subtype, major;
1064 UINT32 value;
1066 hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &major);
1067 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1068 ok(IsEqualGUID(&major, &MFMediaType_Video), "Unexpected major type.\n");
1069 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
1070 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1071 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size);
1072 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1073 ok(frame_size == ((UINT64)100 << 32 | 200), "Unexpected frame size %s.\n", wine_dbgstr_longlong(frame_size));
1074 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
1075 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1076 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value);
1077 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1078 ok(value == MFVideoInterlace_Progressive, "Unexpected interlace mode.\n");
1079 /* Ratio from input type */
1080 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
1081 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1082 ok(ratio == ((UINT64)1 << 32 | 1), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
1083 hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
1084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1085 ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
1086 hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
1087 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1088 ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
1089 hr = IMFMediaType_GetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
1090 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1091 ok(value == 2, "Unexpected value %u.\n", value);
1093 IMFMediaType_Release(media_type);
1095 ok(index > 1, "Unexpected number of available types.\n");
1097 hr = IMFMediaType_DeleteItem(video_type, &MF_MT_FIXED_SIZE_SAMPLES);
1098 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1100 hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
1101 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1103 index = 0;
1104 while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
1106 UINT32 value;
1107 UINT64 ratio;
1109 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
1110 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1111 ok(ratio == ((UINT64)56 << 32 | 55), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
1113 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
1114 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1115 ok(value == 1, "Unexpected value %u.\n", value);
1117 IMFMediaType_Release(media_type);
1119 ok(index > 1, "Unexpected number of available types.\n");
1121 /* Cloned type is returned. */
1122 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1123 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1124 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type2);
1125 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1126 ok(media_type != media_type2, "Unexpected media type instance.\n");
1127 IMFMediaType_Release(media_type);
1128 IMFMediaType_Release(media_type2);
1130 /* Minimal valid attribute set for output type. */
1131 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1132 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1134 hr = MFCreateMediaType(&media_type2);
1135 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1137 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
1138 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1140 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1141 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1142 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &subtype);
1143 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1145 hr = IMFTransform_SetOutputType(transform, 1, NULL, MFT_SET_TYPE_TEST_ONLY);
1146 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1148 hr = IMFTransform_SetOutputType(transform, 0, NULL, MFT_SET_TYPE_TEST_ONLY);
1149 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1151 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1152 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1154 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1155 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1157 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1158 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1160 /* Candidate type have frame size set, mismatching size is accepted. */
1161 hr = IMFMediaType_SetUINT64(media_type2, &MF_MT_FRAME_SIZE, (UINT64)64 << 32 | 64);
1162 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1164 hr = IMFTransform_SetOutputType(transform, 0, media_type2, MFT_SET_TYPE_TEST_ONLY);
1165 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1167 IMFMediaType_Release(media_type2);
1168 IMFMediaType_Release(media_type);
1170 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&processor);
1171 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1173 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1174 todo_wine
1175 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1177 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
1178 todo_wine
1179 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1181 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
1182 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1183 ok(media_type == video_type, "Unexpected pointer.\n");
1184 hr = IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&unk);
1185 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1186 IUnknown_Release(unk);
1187 IMFMediaType_Release(media_type);
1189 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1190 todo_wine
1191 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
1193 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
1194 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1196 hr = IMFTransform_SetOutputType(transform, 1, media_type, 0);
1197 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1199 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
1200 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1202 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
1203 todo_wine
1204 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1206 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
1207 todo_wine
1208 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1209 if (SUCCEEDED(hr))
1210 CoTaskMemFree(guids);
1212 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
1213 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1214 ok(media_type == media_type2, "Unexpected media type instance.\n");
1215 IMFMediaType_Release(media_type2);
1216 IMFMediaType_Release(media_type);
1218 IMFVideoProcessor_Release(processor);
1220 IMFMediaType_Release(video_type);
1222 IDirect3DDeviceManager9_Release(manager);
1224 IDirect3DDevice9_Release(device);
1226 done:
1227 IMFTransform_Release(transform);
1228 DestroyWindow(window);
1231 static void test_default_presenter(void)
1233 IMFVideoDisplayControl *display_control;
1234 IMFVideoPresenter *presenter;
1235 IMFRateSupport *rate_support;
1236 IDirect3DDeviceManager9 *dm;
1237 IMFVideoDeviceID *deviceid;
1238 IUnknown *unk, *unk2;
1239 HWND hwnd, hwnd2;
1240 DWORD flags;
1241 float rate;
1242 HRESULT hr;
1243 GUID iid;
1245 hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter);
1246 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1248 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1249 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1251 check_interface(presenter, &IID_IQualProp, TRUE);
1252 check_interface(presenter, &IID_IMFVideoPositionMapper, TRUE);
1253 check_interface(presenter, &IID_IMFTopologyServiceLookupClient, TRUE);
1254 check_interface(presenter, &IID_IMFVideoDisplayControl, TRUE);
1255 check_interface(presenter, &IID_IMFRateSupport, TRUE);
1256 check_interface(presenter, &IID_IMFGetService, TRUE);
1257 check_interface(presenter, &IID_IMFClockStateSink, TRUE);
1258 check_interface(presenter, &IID_IMFVideoPresenter, TRUE);
1259 check_interface(presenter, &IID_IMFVideoDeviceID, TRUE);
1260 check_interface(presenter, &IID_IMFQualityAdvise, TRUE);
1261 check_interface(presenter, &IID_IDirect3DDeviceManager9, TRUE);
1262 check_interface(presenter, &IID_IMFQualityAdviseLimits, TRUE);
1263 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPositionMapper, TRUE);
1264 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, TRUE);
1265 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoPresenter, TRUE);
1266 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFClockStateSink, TRUE);
1267 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTopologyServiceLookupClient, TRUE);
1268 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IQualProp, TRUE);
1269 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFRateSupport, TRUE);
1270 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFGetService, TRUE);
1271 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDeviceID, TRUE);
1272 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdvise, TRUE);
1273 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFQualityAdviseLimits, TRUE);
1274 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFTransform, FALSE);
1275 check_service_interface(presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1276 check_service_interface(presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, TRUE);
1278 /* Query arbitrary supported interface back from device manager wrapper. */
1279 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IDirect3DDeviceManager9, (void **)&dm);
1280 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1281 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IQualProp, (void **)&unk);
1282 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1283 IUnknown_Release(unk);
1284 hr = IDirect3DDeviceManager9_QueryInterface(dm, &IID_IUnknown, (void **)&unk);
1285 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1286 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IUnknown, (void **)&unk2);
1287 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1288 ok(unk == unk2, "Unexpected interface.\n");
1289 IUnknown_Release(unk2);
1290 IUnknown_Release(unk);
1291 IDirect3DDeviceManager9_Release(dm);
1293 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_MIXER_SERVICE, &IID_IUnknown, (void **)&unk);
1294 ok(hr == MF_E_UNSUPPORTED_SERVICE, "Unexpected hr %#x.\n", hr);
1296 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
1297 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1299 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
1300 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1302 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
1303 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1304 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
1306 IMFVideoDeviceID_Release(deviceid);
1308 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
1309 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1311 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, NULL);
1312 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1314 flags = 123;
1315 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
1316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1317 ok(!flags, "Unexpected rendering flags %#x.\n", flags);
1319 IMFVideoDisplayControl_Release(display_control);
1321 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1322 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1324 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1325 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1327 /* Video window */
1328 hwnd = create_window();
1329 ok(!!hwnd, "Failed to create a test window.\n");
1331 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, NULL);
1332 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1334 hwnd2 = hwnd;
1335 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1336 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1337 ok(hwnd2 == NULL, "Unexpected window %p.\n", hwnd2);
1339 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, NULL);
1340 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1342 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, (HWND)0x1);
1343 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1345 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1346 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1348 hwnd2 = NULL;
1349 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2);
1350 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1351 ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
1353 /* Rate support. */
1354 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
1355 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1357 rate = 1.0f;
1358 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1359 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1360 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1362 rate = 1.0f;
1363 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1364 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1365 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1367 rate = 1.0f;
1368 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1369 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1370 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1372 rate = 1.0f;
1373 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1374 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1375 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1377 IMFRateSupport_Release(rate_support);
1379 IMFVideoPresenter_Release(presenter);
1381 DestroyWindow(hwnd);
1384 static void test_MFCreateVideoMixerAndPresenter(void)
1386 IUnknown *mixer, *presenter;
1387 HRESULT hr;
1389 hr = MFCreateVideoMixerAndPresenter(NULL, NULL, &IID_IUnknown, (void **)&mixer, &IID_IUnknown, (void **)&presenter);
1390 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1392 IUnknown_Release(mixer);
1393 IUnknown_Release(presenter);
1396 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
1397 REFIID riid, void **obj)
1399 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
1400 IsEqualIID(riid, &IID_IUnknown))
1402 *obj = iface;
1403 IMFVideoSampleAllocatorNotify_AddRef(iface);
1404 return S_OK;
1407 *obj = NULL;
1408 return E_NOINTERFACE;
1411 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
1413 return 2;
1416 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
1418 return 1;
1421 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
1423 return E_NOTIMPL;
1426 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
1428 test_notify_callback_QueryInterface,
1429 test_notify_callback_AddRef,
1430 test_notify_callback_Release,
1431 test_notify_callback_NotifyRelease,
1434 static void test_MFCreateVideoSampleAllocator(void)
1436 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
1437 IMFVideoSampleAllocatorCallback *allocator_cb;
1438 IMFMediaType *media_type, *video_type;
1439 IMFVideoSampleAllocator *allocator;
1440 IDirect3DDeviceManager9 *manager;
1441 IMFSample *sample, *sample2;
1442 IDirect3DSurface9 *surface;
1443 IDirect3DDevice9 *device;
1444 IMFMediaBuffer *buffer;
1445 LONG refcount, count;
1446 unsigned int token;
1447 IMFGetService *gs;
1448 IUnknown *unk;
1449 HWND window;
1450 HRESULT hr;
1451 BYTE *data;
1453 hr = MFCreateVideoSampleAllocator(&IID_IUnknown, (void **)&unk);
1454 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1455 IUnknown_Release(unk);
1457 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1458 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1460 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
1461 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1463 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1464 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1466 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
1467 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1469 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
1470 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1472 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
1473 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1475 count = 10;
1476 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1477 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1478 ok(!count, "Unexpected count %d.\n", count);
1480 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
1481 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1483 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1484 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1486 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
1487 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1489 hr = MFCreateMediaType(&media_type);
1490 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1492 /* It expects IMFVideoMediaType aka video major type. Exact return code is E_NOINTERFACE,
1493 likely coming from querying for IMFVideoMediaType. Does not seem valuable to match it. */
1494 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
1495 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1497 video_type = create_video_type(&MFVideoFormat_RGB32);
1499 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
1500 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1502 /* Frame size is required. */
1503 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1504 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1505 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1506 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1508 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1509 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1510 ok(count == 1, "Unexpected count %d.\n", count);
1512 sample = NULL;
1513 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1514 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1515 refcount = get_refcount(sample);
1517 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
1518 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
1520 /* Reinitialize with active sample. */
1521 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 4, video_type);
1522 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1523 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
1525 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1526 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1527 ok(count == 4, "Unexpected count %d.\n", count);
1529 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1530 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1532 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1533 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1535 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1537 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
1538 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#x.\n", hr);
1540 /* Device manager wasn't set, sample gets regular memory buffers. */
1541 if (SUCCEEDED(hr))
1543 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1544 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
1545 IMFGetService_Release(gs);
1548 IMFMediaBuffer_Release(buffer);
1550 IMFSample_Release(sample);
1552 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
1554 IMFVideoSampleAllocator_Release(allocator);
1556 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocatorCallback, (void **)&unk);
1557 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1558 IUnknown_Release(unk);
1560 /* Using device manager */
1561 window = create_window();
1562 if (!(device = create_device(window)))
1564 skip("Failed to create a D3D device, skipping tests.\n");
1565 goto done;
1568 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
1569 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1570 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
1571 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
1573 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1574 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1576 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
1577 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1579 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1580 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1581 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
1582 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1584 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1585 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1587 check_interface(sample, &IID_IMFTrackedSample, TRUE);
1588 check_interface(sample, &IID_IMFDesiredSample, TRUE);
1590 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1591 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1593 check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE);
1594 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
1595 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
1597 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1598 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1600 hr = IMFMediaBuffer_Unlock(buffer);
1601 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1603 IMFSample_Release(sample);
1605 IMFVideoSampleAllocator_Release(allocator);
1607 IMFMediaType_Release(media_type);
1608 IDirect3DDeviceManager9_Release(manager);
1609 IDirect3DDevice9_Release(device);
1610 done:
1611 DestroyWindow(window);
1614 struct test_host
1616 IMFTopologyServiceLookup IMFTopologyServiceLookup_iface;
1617 IMediaEventSink IMediaEventSink_iface;
1618 IMFTransform *mixer;
1619 IMFVideoPresenter *presenter;
1622 static struct test_host *impl_from_test_host(IMFTopologyServiceLookup *iface)
1624 return CONTAINING_RECORD(iface, struct test_host, IMFTopologyServiceLookup_iface);
1627 static struct test_host *impl_from_test_host_events(IMediaEventSink *iface)
1629 return CONTAINING_RECORD(iface, struct test_host, IMediaEventSink_iface);
1632 static HRESULT WINAPI test_host_QueryInterface(IMFTopologyServiceLookup *iface, REFIID riid, void **obj)
1634 if (IsEqualIID(riid, &IID_IMFTopologyServiceLookup) ||
1635 IsEqualIID(riid, &IID_IUnknown))
1637 *obj = iface;
1638 IMFTopologyServiceLookup_AddRef(iface);
1639 return S_OK;
1642 *obj = NULL;
1643 return E_NOINTERFACE;
1646 static ULONG WINAPI test_host_AddRef(IMFTopologyServiceLookup *iface)
1648 return 2;
1651 static ULONG WINAPI test_host_Release(IMFTopologyServiceLookup *iface)
1653 return 1;
1656 static HRESULT WINAPI test_host_LookupService(IMFTopologyServiceLookup *iface,
1657 MF_SERVICE_LOOKUP_TYPE lookup_type, DWORD index, REFGUID service,
1658 REFIID riid, void **objects, DWORD *num_objects)
1660 struct test_host *host = impl_from_test_host(iface);
1662 ok(*num_objects == 1, "Unexpected number of requested objects %u\n", *num_objects);
1664 memset(objects, 0, *num_objects * sizeof(*objects));
1666 if (IsEqualGUID(service, &MR_VIDEO_RENDER_SERVICE))
1668 if (IsEqualIID(riid, &IID_IMFClock)) return E_FAIL;
1669 if (IsEqualIID(riid, &IID_IMediaEventSink))
1671 *objects = &host->IMediaEventSink_iface;
1672 IMediaEventSink_AddRef(&host->IMediaEventSink_iface);
1673 return S_OK;
1676 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1677 return E_UNEXPECTED;
1680 if (IsEqualGUID(service, &MR_VIDEO_MIXER_SERVICE))
1682 if (IsEqualIID(riid, &IID_IMFTransform))
1684 *objects = host->mixer;
1685 IMFTransform_AddRef(host->mixer);
1686 return S_OK;
1688 ok(0, "Unexpected interface %s.\n", wine_dbgstr_guid(riid));
1689 return E_UNEXPECTED;
1692 return E_NOTIMPL;
1695 static const IMFTopologyServiceLookupVtbl test_host_vtbl =
1697 test_host_QueryInterface,
1698 test_host_AddRef,
1699 test_host_Release,
1700 test_host_LookupService,
1703 static HRESULT WINAPI test_host_events_QueryInterface(IMediaEventSink *iface, REFIID riid, void **obj)
1705 struct test_host *host = impl_from_test_host_events(iface);
1706 return IMFTopologyServiceLookup_QueryInterface(&host->IMFTopologyServiceLookup_iface, riid, obj);
1709 static ULONG WINAPI test_host_events_AddRef(IMediaEventSink *iface)
1711 struct test_host *host = impl_from_test_host_events(iface);
1712 return IMFTopologyServiceLookup_AddRef(&host->IMFTopologyServiceLookup_iface);
1715 static ULONG WINAPI test_host_events_Release(IMediaEventSink *iface)
1717 struct test_host *host = impl_from_test_host_events(iface);
1718 return IMFTopologyServiceLookup_Release(&host->IMFTopologyServiceLookup_iface);
1721 static HRESULT WINAPI test_host_events_Notify(IMediaEventSink *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
1723 return S_OK;
1726 static const IMediaEventSinkVtbl test_host_events_vtbl =
1728 test_host_events_QueryInterface,
1729 test_host_events_AddRef,
1730 test_host_events_Release,
1731 test_host_events_Notify,
1734 static void init_test_host(struct test_host *host, IMFTransform *mixer, IMFVideoPresenter *presenter)
1736 host->IMFTopologyServiceLookup_iface.lpVtbl = &test_host_vtbl;
1737 host->IMediaEventSink_iface.lpVtbl = &test_host_events_vtbl;
1738 /* No need to keep references. */
1739 host->mixer = mixer;
1740 host->presenter = presenter;
1743 static void test_presenter_video_position(void)
1745 IMFTopologyServiceLookupClient *lookup_client;
1746 IMFVideoDisplayControl *display_control;
1747 IMFAttributes *mixer_attributes;
1748 MFVideoNormalizedRect src_rect;
1749 IMFVideoPresenter *presenter;
1750 struct test_host host;
1751 IMFTransform *mixer;
1752 RECT dst_rect;
1753 HRESULT hr;
1754 DWORD count;
1755 HWND hwnd;
1757 hwnd = create_window();
1758 ok(!!hwnd, "Failed to create a test window.\n");
1760 /* Setting position without the mixer. */
1761 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1762 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1763 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1764 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1766 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
1767 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1768 SetRect(&dst_rect, 0, 0, 10, 10);
1769 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1770 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1771 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1772 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1774 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
1775 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1776 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1777 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1779 IMFVideoDisplayControl_Release(display_control);
1780 IMFVideoPresenter_Release(presenter);
1782 /* With the mixer. */
1783 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1784 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1786 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1787 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1789 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1790 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1792 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1793 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1795 init_test_host(&host, mixer, presenter);
1797 /* Clear default mixer attributes, then attach presenter. */
1798 hr = IMFTransform_GetAttributes(mixer, &mixer_attributes);
1799 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1801 hr = IMFAttributes_DeleteAllItems(mixer_attributes);
1802 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1804 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1805 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1807 hr = IMFAttributes_GetCount(mixer_attributes, &count);
1808 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1809 ok(count == 1, "Unexpected count %u.\n", count);
1811 memset(&src_rect, 0, sizeof(src_rect));
1812 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1814 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1815 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1817 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &dst_rect);
1818 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1820 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, NULL);
1821 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1823 SetRect(&dst_rect, 1, 2, 3, 4);
1824 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1825 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1826 ok(src_rect.left == 0.0f && src_rect.top == 0.0f && src_rect.right == 1.0f &&
1827 src_rect.bottom == 1.0f, "Unexpected source rectangle.\n");
1828 ok(dst_rect.left == 0 && dst_rect.right == 0 && dst_rect.top == 0 && dst_rect.bottom == 0,
1829 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1831 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, NULL);
1832 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1834 /* Setting position requires a window. */
1835 SetRect(&dst_rect, 0, 0, 10, 10);
1836 memset(&src_rect, 0, sizeof(src_rect));
1837 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, &dst_rect);
1838 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1840 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd);
1841 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1843 SetRect(&dst_rect, 0, 0, 10, 10);
1844 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1845 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1847 SetRect(&dst_rect, 1, 2, 3, 4);
1848 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1849 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1850 ok(dst_rect.left == 0 && dst_rect.right == 10 && dst_rect.top == 0 && dst_rect.bottom == 10,
1851 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1853 set_rect(&src_rect, 0.0f, 0.0f, 2.0f, 1.0f);
1854 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1855 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1857 set_rect(&src_rect, -0.1f, 0.0f, 0.9f, 1.0f);
1858 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1859 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1861 /* Flipped source rectangle. */
1862 set_rect(&src_rect, 0.5f, 0.0f, 0.4f, 1.0f);
1863 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1864 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1866 set_rect(&src_rect, 0.0f, 0.5f, 0.4f, 0.1f);
1867 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1868 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1870 set_rect(&src_rect, 0.1f, 0.2f, 0.8f, 0.9f);
1871 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL);
1872 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1874 /* Presenter updates mixer attribute. */
1875 memset(&src_rect, 0, sizeof(src_rect));
1876 hr = IMFAttributes_GetBlob(mixer_attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&src_rect, sizeof(src_rect), NULL);
1877 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1878 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1879 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1881 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1883 ok(src_rect.left == 0.1f && src_rect.top == 0.2f && src_rect.right == 0.8f &&
1884 src_rect.bottom == 0.9f, "Unexpected source rectangle.\n");
1886 SetRect(&dst_rect, 1, 2, 999, 1000);
1887 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1888 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1890 SetRect(&dst_rect, 0, 1, 3, 4);
1891 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, &src_rect, &dst_rect);
1892 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1893 ok(dst_rect.left == 1 && dst_rect.right == 999 && dst_rect.top == 2 && dst_rect.bottom == 1000,
1894 "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
1896 /* Flipped destination rectangle. */
1897 SetRect(&dst_rect, 100, 1, 50, 1000);
1898 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1899 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1901 SetRect(&dst_rect, 1, 100, 100, 50);
1902 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst_rect);
1903 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1905 IMFVideoDisplayControl_Release(display_control);
1907 IMFTopologyServiceLookupClient_Release(lookup_client);
1908 IMFVideoPresenter_Release(presenter);
1909 IMFAttributes_Release(mixer_attributes);
1910 IMFTransform_Release(mixer);
1912 DestroyWindow(hwnd);
1915 static void test_presenter_native_video_size(void)
1917 IMFTopologyServiceLookupClient *lookup_client;
1918 IMFVideoDisplayControl *display_control;
1919 IMFVideoPresenter *presenter;
1920 struct test_host host;
1921 IMFTransform *mixer;
1922 SIZE size, ratio;
1923 HRESULT hr;
1924 IMFMediaType *video_type;
1925 IDirect3DDeviceManager9 *dm;
1927 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
1928 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
1930 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
1931 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
1933 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1934 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1936 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
1937 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1939 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, NULL);
1940 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1942 memset(&size, 0xcc, sizeof(size));
1943 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, NULL);
1944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1945 ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n");
1947 memset(&ratio, 0xcc, sizeof(ratio));
1948 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, &ratio);
1949 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1950 ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n");
1952 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
1953 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1955 /* Configure mixer primary stream. */
1956 hr = MFGetService((IUnknown *)presenter, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
1957 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1959 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)dm);
1960 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1962 IDirect3DDeviceManager9_Release(dm);
1964 video_type = create_video_type(&MFVideoFormat_RGB32);
1966 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
1967 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1968 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
1969 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1971 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1972 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1974 /* Native video size is cached on initialization. */
1975 init_test_host(&host, mixer, presenter);
1977 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
1978 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1980 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1981 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1982 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1983 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1984 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1986 /* Update input type. */
1987 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)320 << 32 | 240);
1988 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1990 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
1991 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1993 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
1994 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1995 ok(size.cx == 640 && size.cy == 480, "Unexpected size %u x %u.\n", size.cx, size.cy);
1996 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
1997 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
1999 /* Negotiating types updates native video size. */
2000 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2001 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2003 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio);
2004 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2005 ok(size.cx == 320 && size.cy == 240, "Unexpected size %u x %u.\n", size.cx, size.cy);
2006 ok((ratio.cx == 4 && ratio.cy == 3) || broken(!memcmp(&ratio, &size, sizeof(ratio))) /* < Win10 */,
2007 "Unexpected ratio %u x %u.\n", ratio.cx, ratio.cy);
2009 IMFMediaType_Release(video_type);
2010 IMFVideoDisplayControl_Release(display_control);
2011 IMFVideoPresenter_Release(presenter);
2012 IMFTransform_Release(mixer);
2015 static void test_presenter_ar_mode(void)
2017 IMFVideoDisplayControl *display_control;
2018 HRESULT hr;
2019 DWORD mode;
2021 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
2022 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2024 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, NULL);
2025 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2027 mode = 0;
2028 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2029 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2030 ok(mode == (MFVideoARMode_PreservePicture | MFVideoARMode_PreservePixel), "Unexpected mode %#x.\n", mode);
2032 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, 0x100);
2033 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2035 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_Mask);
2036 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2038 mode = 0;
2039 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2040 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2041 ok(mode == MFVideoARMode_Mask, "Unexpected mode %#x.\n", mode);
2043 IMFVideoDisplayControl_Release(display_control);
2046 static void test_presenter_video_window(void)
2048 D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
2049 IMFVideoDisplayControl *display_control;
2050 IDirect3DDeviceManager9 *dm;
2051 IDirect3DDevice9 *d3d_device;
2052 HANDLE hdevice;
2053 HRESULT hr;
2054 IDirect3DSwapChain9 *swapchain;
2055 D3DPRESENT_PARAMETERS present_params = { 0 };
2056 HWND window;
2058 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
2059 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2061 hr = MFGetService((IUnknown *)display_control, &MR_VIDEO_ACCELERATION_SERVICE,
2062 &IID_IDirect3DDeviceManager9, (void **)&dm);
2064 hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &hdevice);
2065 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2067 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
2068 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2070 hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
2071 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2072 ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
2074 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
2075 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2077 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
2078 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2080 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
2081 ok(present_params.Windowed, "Unexpected windowed mode.\n");
2082 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
2083 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
2084 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
2086 IDirect3DSwapChain9_Release(swapchain);
2087 IDirect3DDevice9_Release(d3d_device);
2089 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
2090 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2092 /* Setting window. */
2093 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window);
2094 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2095 ok(!window, "Unexpected window %p.\n", window);
2097 window = create_window();
2099 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2100 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2102 /* Device is not recreated or reset on window change. */
2103 hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
2104 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2106 hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
2107 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2109 hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
2110 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2112 ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
2113 ok(present_params.Windowed, "Unexpected windowed mode.\n");
2114 ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
2115 ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
2116 ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
2118 IDirect3DSwapChain9_Release(swapchain);
2119 IDirect3DDevice9_Release(d3d_device);
2121 hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
2122 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2124 hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, hdevice);
2125 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2127 IMFVideoDisplayControl_Release(display_control);
2129 DestroyWindow(window);
2132 static void test_presenter_quality_control(void)
2134 IMFQualityAdviseLimits *qa_limits;
2135 IMFVideoPresenter *presenter;
2136 MF_QUALITY_DROP_MODE mode;
2137 IMFQualityAdvise *advise;
2138 MF_QUALITY_LEVEL level;
2139 HRESULT hr;
2141 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2142 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2144 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdviseLimits, (void **)&qa_limits);
2145 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2147 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFQualityAdvise, (void **)&advise);
2148 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2150 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, NULL);
2151 todo_wine
2152 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2154 hr = IMFQualityAdviseLimits_GetMaximumDropMode(qa_limits, &mode);
2155 todo_wine
2156 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2157 if (SUCCEEDED(hr))
2158 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2160 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, NULL);
2161 todo_wine
2162 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2164 hr = IMFQualityAdviseLimits_GetMinimumQualityLevel(qa_limits, &level);
2165 todo_wine
2166 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2167 if (SUCCEEDED(hr))
2168 ok(level == MF_QUALITY_NORMAL, "Unexpected level %d.\n", level);
2170 IMFQualityAdviseLimits_Release(qa_limits);
2172 todo_wine {
2173 mode = 1;
2174 hr = IMFQualityAdvise_GetDropMode(advise, &mode);
2175 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2176 ok(mode == MF_DROP_MODE_NONE, "Unexpected mode %d.\n", mode);
2178 level = 1;
2179 hr = IMFQualityAdvise_GetQualityLevel(advise, &level);
2180 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2181 ok(level == MF_QUALITY_NORMAL, "Unexpected mode %d.\n", level);
2183 hr = IMFQualityAdvise_SetDropMode(advise, MF_DROP_MODE_1);
2184 ok(hr == MF_E_NO_MORE_DROP_MODES, "Unexpected hr %#x.\n", hr);
2186 hr = IMFQualityAdvise_SetQualityLevel(advise, MF_QUALITY_NORMAL_MINUS_1);
2187 ok(hr == MF_E_NO_MORE_QUALITY_LEVELS, "Unexpected hr %#x.\n", hr);
2190 IMFQualityAdvise_Release(advise);
2192 IMFVideoPresenter_Release(presenter);
2195 static void get_output_aperture(IMFTransform *mixer, SIZE *frame_size, MFVideoArea *aperture)
2197 IMFMediaType *media_type;
2198 UINT64 size;
2199 HRESULT hr;
2201 memset(frame_size, 0xcc, sizeof(*frame_size));
2202 memset(aperture, 0xcc, sizeof(*aperture));
2204 hr = IMFTransform_GetOutputCurrentType(mixer, 0, &media_type);
2205 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2207 hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &size);
2208 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2210 frame_size->cx = size >> 32;
2211 frame_size->cy = size;
2213 hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)aperture, sizeof(*aperture), NULL);
2214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2216 IMFMediaType_Release(media_type);
2219 static void test_presenter_media_type(void)
2221 IMFTopologyServiceLookupClient *lookup_client;
2222 IMFVideoPresenter *presenter;
2223 struct test_host host;
2224 IMFMediaType *input_type;
2225 IDirect3DDeviceManager9 *manager;
2226 HRESULT hr;
2227 IMFTransform *mixer;
2228 IDirect3DDevice9 *device;
2229 unsigned int token;
2230 SIZE frame_size;
2231 HWND window;
2232 MFVideoArea aperture;
2233 IMFVideoDisplayControl *display_control;
2234 RECT dst;
2236 window = create_window();
2237 if (!(device = create_device(window)))
2239 skip("Failed to create a D3D device, skipping tests.\n");
2240 goto done;
2243 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2244 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2246 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2247 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2249 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2250 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2252 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2253 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2255 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2256 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2258 input_type = create_video_type(&MFVideoFormat_RGB32);
2260 hr = IMFMediaType_SetUINT64(input_type, &MF_MT_FRAME_SIZE, (UINT64)100 << 32 | 50);
2261 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2262 hr = IMFMediaType_SetUINT32(input_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2263 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2265 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2266 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2268 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2269 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2271 init_test_host(&host, mixer, presenter);
2273 hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface);
2274 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2276 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2277 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2279 /* Set destination rectangle before mixer types are configured. */
2280 SetRect(&dst, 0, 0, 101, 51);
2281 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
2282 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2284 hr = IMFTransform_SetInputType(mixer, 0, input_type, 0);
2285 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2287 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2288 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2290 get_output_aperture(mixer, &frame_size, &aperture);
2291 ok(frame_size.cx == 101 && frame_size.cy == 51, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2292 ok(aperture.Area.cx == 101 && aperture.Area.cy == 51, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2293 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2294 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2296 SetRect(&dst, 1, 2, 200, 300);
2297 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &dst);
2298 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2300 get_output_aperture(mixer, &frame_size, &aperture);
2301 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2302 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2303 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2304 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2306 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
2307 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2309 get_output_aperture(mixer, &frame_size, &aperture);
2310 ok(frame_size.cx == 199 && frame_size.cy == 298, "Unexpected frame size %u x %u.\n", frame_size.cx, frame_size.cy);
2311 ok(aperture.Area.cx == 199 && aperture.Area.cy == 298, "Unexpected size %u x %u.\n", aperture.Area.cx, aperture.Area.cy);
2312 ok(!aperture.OffsetX.value && !aperture.OffsetX.fract && !aperture.OffsetY.value && !aperture.OffsetY.fract,
2313 "Unexpected offset %u x %u.\n", aperture.OffsetX.value, aperture.OffsetY.value);
2315 IMFVideoDisplayControl_Release(display_control);
2316 IMFVideoPresenter_Release(presenter);
2317 IMFTransform_Release(mixer);
2319 done:
2320 DestroyWindow(window);
2323 static void test_presenter_shutdown(void)
2325 IMFTopologyServiceLookupClient *lookup_client;
2326 IMFVideoDisplayControl *display_control;
2327 IMFVideoMediaType *media_type;
2328 IMFVideoPresenter *presenter;
2329 IMFVideoDeviceID *deviceid;
2330 HWND window, window2;
2331 HRESULT hr;
2332 DWORD mode;
2333 RECT rect;
2334 SIZE size;
2335 IID iid;
2337 window = create_window();
2338 ok(!!window, "Failed to create test window.\n");
2340 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
2341 ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
2343 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client);
2344 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2346 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
2347 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2349 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
2350 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2352 hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client);
2353 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2355 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_INVALIDATEMEDIATYPE, 0);
2356 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2358 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_BEGINSTREAMING, 0);
2359 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2361 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_ENDSTREAMING, 0);
2362 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2364 hr = IMFVideoPresenter_ProcessMessage(presenter, MFVP_MESSAGE_PROCESSINPUTNOTIFY, 0);
2365 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2367 hr = IMFVideoPresenter_GetCurrentMediaType(presenter, &media_type);
2368 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2370 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
2371 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2373 hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &size);
2374 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2376 hr = IMFVideoDisplayControl_GetIdealVideoSize(display_control, &size, &size);
2377 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2379 SetRect(&rect, 0, 0, 10, 10);
2380 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &rect);
2381 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2383 hr = IMFVideoDisplayControl_GetVideoPosition(display_control, NULL, &rect);
2384 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2386 hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, MFVideoARMode_None);
2387 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2389 hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, &mode);
2390 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2392 hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
2393 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2395 hr = IMFVideoDisplayControl_SetVideoPosition(display_control, NULL, &rect);
2396 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2398 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window2);
2399 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2401 hr = IMFVideoDisplayControl_RepaintVideo(display_control);
2402 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2404 hr = IMFTopologyServiceLookupClient_ReleaseServicePointers(lookup_client);
2405 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2407 IMFVideoDeviceID_Release(deviceid);
2408 IMFVideoDisplayControl_Release(display_control);
2409 IMFTopologyServiceLookupClient_Release(lookup_client);
2411 IMFVideoPresenter_Release(presenter);
2413 DestroyWindow(window);
2416 static void test_mixer_output_rectangle(void)
2418 IMFVideoMixerControl *mixer_control;
2419 MFVideoNormalizedRect rect;
2420 IMFTransform *mixer;
2421 HRESULT hr;
2423 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2424 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2426 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2427 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2429 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, NULL);
2430 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2432 set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f);
2433 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, &rect);
2434 ok(hr == S_OK, "Failed to get output rect, hr %#x.\n", hr);
2435 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
2436 "Unexpected rectangle.\n");
2438 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, &rect);
2439 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2441 hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, NULL);
2442 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2444 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, &rect);
2445 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2447 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, NULL);
2448 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2450 /* Wrong bounds. */
2451 set_rect(&rect, 0.0f, 0.0f, 1.1f, 1.0f);
2452 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2453 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2455 set_rect(&rect, -0.1f, 0.0f, 0.5f, 1.0f);
2456 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2457 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2459 /* Flipped. */
2460 set_rect(&rect, 1.0f, 0.0f, 0.0f, 1.0f);
2461 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2462 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2464 set_rect(&rect, 0.0f, 1.0f, 1.0f, 0.5f);
2465 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect);
2466 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2468 hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, NULL);
2469 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2471 IMFVideoMixerControl_Release(mixer_control);
2472 IMFTransform_Release(mixer);
2475 static void test_mixer_zorder(void)
2477 IMFVideoMixerControl *mixer_control;
2478 IMFTransform *mixer;
2479 DWORD ids[2];
2480 DWORD value;
2481 HRESULT hr;
2483 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2484 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2486 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control);
2487 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2489 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, NULL);
2490 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2492 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, NULL);
2493 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2495 value = 1;
2496 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, &value);
2497 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2498 ok(!value, "Unexpected value %u.\n", value);
2500 value = 1;
2501 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2502 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2504 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 1);
2505 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2507 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 1);
2508 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2510 /* Exceeds maximum stream number. */
2511 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 20);
2512 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2514 value = 1;
2515 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2516 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2518 value = 0;
2519 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2520 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2521 ok(value == 1, "Unexpected zorder %u.\n", value);
2523 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 0);
2524 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
2526 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 2);
2527 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2529 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 0);
2530 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2532 value = 2;
2533 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2534 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2536 value = 0;
2537 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2538 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2539 ok(value == 2, "Unexpected zorder %u.\n", value);
2541 hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 2, 1);
2542 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2544 value = 3;
2545 hr = IMFTransform_AddInputStreams(mixer, 1, &value);
2546 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2548 value = 0;
2549 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 3, &value);
2550 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2551 ok(value == 3, "Unexpected zorder %u.\n", value);
2553 hr = IMFTransform_DeleteInputStream(mixer, 1);
2554 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2555 hr = IMFTransform_DeleteInputStream(mixer, 2);
2556 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2557 hr = IMFTransform_DeleteInputStream(mixer, 3);
2558 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2560 ids[0] = 2;
2561 ids[1] = 1;
2562 hr = IMFTransform_AddInputStreams(mixer, 2, ids);
2563 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2565 value = 0;
2566 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value);
2567 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2568 ok(value == 2, "Unexpected zorder %u.\n", value);
2570 value = 0;
2571 hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value);
2572 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2573 ok(value == 1, "Unexpected zorder %u.\n", value);
2575 IMFVideoMixerControl_Release(mixer_control);
2576 IMFTransform_Release(mixer);
2579 static IDirect3DSurface9 * create_surface(IDirect3DDeviceManager9 *manager, unsigned int width,
2580 unsigned int height)
2582 IDirectXVideoAccelerationService *service;
2583 IDirect3DSurface9 *surface = NULL;
2584 IDirect3DDevice9 *device;
2585 HANDLE handle;
2586 HRESULT hr;
2588 hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle);
2589 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2591 hr = IDirect3DDeviceManager9_LockDevice(manager, handle, &device, TRUE);
2592 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2594 hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
2595 (void **)&service);
2596 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2598 hr = IDirectXVideoAccelerationService_CreateSurface(service, width, height, 0, D3DFMT_A8R8G8B8,
2599 D3DPOOL_DEFAULT, 0, DXVA2_VideoProcessorRenderTarget, &surface, NULL);
2600 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2602 IDirectXVideoAccelerationService_Release(service);
2604 hr = IDirect3DDevice9_ColorFill(device, surface, NULL, D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00));
2605 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2607 IDirect3DDevice9_Release(device);
2609 hr = IDirect3DDeviceManager9_UnlockDevice(manager, handle, FALSE);
2610 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2612 hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
2613 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2615 return surface;
2618 /* Format is assumed as 32bpp */
2619 static DWORD get_surface_color(IDirect3DSurface9 *surface, unsigned int x, unsigned int y)
2621 D3DLOCKED_RECT locked_rect = { 0 };
2622 D3DSURFACE_DESC desc;
2623 DWORD *row, color;
2624 HRESULT hr;
2626 hr = IDirect3DSurface9_GetDesc(surface, &desc);
2627 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2628 ok(x < desc.Width && y < desc.Height, "Invalid coordinate.\n");
2629 if (x >= desc.Width || y >= desc.Height) return 0;
2631 hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, 0);
2632 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2634 row = (DWORD *)((char *)locked_rect.pBits + y * locked_rect.Pitch);
2635 color = row[x];
2637 hr = IDirect3DSurface9_UnlockRect(surface);
2638 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2640 return color;
2643 static void test_mixer_samples(void)
2645 IDirect3DDeviceManager9 *manager;
2646 MFT_OUTPUT_DATA_BUFFER buffers[2];
2647 IMFVideoProcessor *processor;
2648 IDirect3DSurface9 *surface;
2649 IMFDesiredSample *desired;
2650 IDirect3DDevice9 *device;
2651 IMFMediaType *video_type;
2652 DWORD count, flags, color, status;
2653 IMFTransform *mixer;
2654 IMFSample *sample, *sample2;
2655 HWND window;
2656 UINT token;
2657 HRESULT hr;
2658 LONGLONG pts, duration;
2660 window = create_window();
2661 if (!(device = create_device(window)))
2663 skip("Failed to create a D3D device, skipping tests.\n");
2664 goto done;
2667 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer);
2668 ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr);
2670 hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoProcessor, (void **)&processor);
2671 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2673 hr = IMFTransform_GetInputStatus(mixer, 0, NULL);
2674 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2676 hr = IMFTransform_GetInputStatus(mixer, 1, NULL);
2677 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2679 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2680 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2682 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2683 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2685 hr = IMFTransform_GetOutputStatus(mixer, NULL);
2686 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2688 hr = IMFTransform_GetOutputStatus(mixer, &status);
2689 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2691 /* Configure device and media types. */
2692 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
2693 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2695 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
2696 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
2698 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
2699 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2701 video_type = create_video_type(&MFVideoFormat_RGB32);
2703 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
2704 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2705 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2706 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2708 hr = IMFTransform_SetInputType(mixer, 0, video_type, 0);
2709 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2711 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2712 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2714 hr = IMFTransform_SetOutputType(mixer, 0, video_type, 0);
2715 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2717 status = 0;
2718 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2719 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2720 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2722 hr = IMFTransform_GetInputStatus(mixer, 1, &status);
2723 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2725 status = ~0u;
2726 hr = IMFTransform_GetOutputStatus(mixer, &status);
2727 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2728 ok(!status, "Unexpected status %#x.\n", status);
2730 IMFMediaType_Release(video_type);
2732 memset(buffers, 0, sizeof(buffers));
2733 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2734 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2736 /* It needs a sample with a backing surface. */
2737 hr = MFCreateSample(&sample);
2738 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2740 buffers[0].pSample = sample;
2741 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2742 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2744 IMFSample_Release(sample);
2746 surface = create_surface(manager, 64, 64);
2748 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample);
2749 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2751 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired);
2752 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2754 buffers[0].pSample = sample;
2755 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2756 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2758 color = get_surface_color(surface, 0, 0);
2759 ok(color == D3DCOLOR_ARGB(0x10, 0xff, 0x00, 0x00), "Unexpected color %#x.\n", color);
2761 /* Streaming is not started yet. Output is colored black, but only if desired timestamps were set. */
2762 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired, 100, 0);
2764 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2765 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2767 color = get_surface_color(surface, 0, 0);
2768 ok(!color, "Unexpected color %#x.\n", color);
2770 hr = IMFVideoProcessor_SetBackgroundColor(processor, RGB(0, 0, 255));
2771 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2773 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2774 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2776 color = get_surface_color(surface, 0, 0);
2777 ok(!color, "Unexpected color %#x.\n", color);
2779 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
2780 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2782 buffers[1].pSample = sample;
2783 hr = IMFTransform_ProcessOutput(mixer, 0, 2, buffers, &status);
2784 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2786 buffers[0].dwStreamID = 1;
2787 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2788 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2790 IMFDesiredSample_Clear(desired);
2792 hr = IMFTransform_ProcessInput(mixer, 0, NULL, 0);
2793 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2795 hr = IMFTransform_ProcessInput(mixer, 5, NULL, 0);
2796 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2798 status = 0;
2799 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2800 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2801 ok(status == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected status %#x.\n", status);
2803 status = ~0u;
2804 hr = IMFTransform_GetOutputStatus(mixer, &status);
2805 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2806 ok(!status, "Unexpected status %#x.\n", status);
2808 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2809 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2811 status = ~0u;
2812 hr = IMFTransform_GetInputStatus(mixer, 0, &status);
2813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2814 ok(!status, "Unexpected status %#x.\n", status);
2816 hr = IMFTransform_GetOutputStatus(mixer, &status);
2817 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2818 ok(status == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected status %#x.\n", status);
2820 hr = IMFTransform_ProcessInput(mixer, 0, sample, 0);
2821 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
2823 hr = IMFTransform_ProcessInput(mixer, 5, sample, 0);
2824 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2826 /* ProcessOutput() sets sample time and duration. */
2827 hr = MFCreateVideoSampleFromSurface((IUnknown *)surface, &sample2);
2828 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2830 hr = IMFSample_SetUINT32(sample2, &IID_IMFSample, 1);
2831 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2833 hr = IMFSample_SetSampleFlags(sample2, 0x123);
2834 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2836 hr = IMFSample_GetSampleTime(sample2, &pts);
2837 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2839 hr = IMFSample_GetSampleDuration(sample2, &duration);
2840 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2842 hr = IMFSample_SetSampleTime(sample, 0);
2843 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2845 hr = IMFSample_SetSampleDuration(sample, 0);
2846 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2848 memset(buffers, 0, sizeof(buffers));
2849 buffers[0].pSample = sample2;
2850 hr = IMFTransform_ProcessOutput(mixer, 0, 1, buffers, &status);
2851 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2853 hr = IMFSample_GetSampleTime(sample2, &pts);
2854 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2855 ok(!pts, "Unexpected sample time.\n");
2857 hr = IMFSample_GetSampleDuration(sample2, &duration);
2858 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2859 ok(!duration, "Unexpected duration\n");
2861 /* Flags are not copied. */
2862 hr = IMFSample_GetSampleFlags(sample2, &flags);
2863 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2864 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2866 /* Attributes are not removed. */
2867 hr = IMFSample_GetCount(sample2, &count);
2868 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2869 ok(count == 1, "Unexpected attribute count %u.\n", count);
2871 hr = IMFSample_GetCount(sample, &count);
2872 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2873 ok(!count, "Unexpected attribute count %u.\n", count);
2875 IMFSample_Release(sample2);
2877 hr = IMFTransform_ProcessMessage(mixer, MFT_MESSAGE_COMMAND_DRAIN, 0);
2878 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2880 IMFSample_Release(sample);
2882 IDirect3DSurface9_Release(surface);
2884 IMFVideoProcessor_Release(processor);
2885 IMFTransform_Release(mixer);
2887 IDirect3DDevice9_Release(device);
2888 IDirect3DDeviceManager9_Release(manager);
2890 done:
2891 DestroyWindow(window);
2894 static void test_MFIsFormatYUV(void)
2896 static const DWORD formats[] =
2898 D3DFMT_UYVY,
2899 D3DFMT_YUY2,
2900 MAKEFOURCC('A','Y','U','V'),
2901 MAKEFOURCC('I','M','C','1'),
2902 MAKEFOURCC('I','M','C','2'),
2903 MAKEFOURCC('Y','V','1','2'),
2904 MAKEFOURCC('N','V','1','1'),
2905 MAKEFOURCC('N','V','1','2'),
2906 MAKEFOURCC('Y','2','1','0'),
2907 MAKEFOURCC('Y','2','1','6'),
2909 static const DWORD unsupported_formats[] =
2911 D3DFMT_A8R8G8B8,
2912 MAKEFOURCC('I','Y','U','V'),
2913 MAKEFOURCC('I','4','2','0'),
2914 MAKEFOURCC('Y','V','Y','U'),
2915 MAKEFOURCC('Y','V','U','9'),
2916 MAKEFOURCC('Y','4','1','0'),
2917 MAKEFOURCC('Y','4','1','6'),
2919 unsigned int i;
2920 BOOL ret;
2922 for (i = 0; i < ARRAY_SIZE(formats); ++i)
2924 ret = MFIsFormatYUV(formats[i]);
2925 ok(ret, "Unexpected ret %d, format %s.\n", ret, debugstr_an((char *)&formats[i], 4));
2928 for (i = 0; i < ARRAY_SIZE(unsupported_formats); ++i)
2930 ret = MFIsFormatYUV(unsupported_formats[i]);
2931 ok(!ret, "Unexpected ret %d, format %s.\n", ret, debugstr_an((char *)&unsupported_formats[i], 4));
2935 START_TEST(evr)
2937 IMFVideoPresenter *presenter;
2938 HRESULT hr;
2940 CoInitialize(NULL);
2942 if (FAILED(hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter)))
2944 win_skip("Failed to create default presenter, hr %#x. Skipping tests.\n", hr);
2945 CoUninitialize();
2946 return;
2948 IMFVideoPresenter_Release(presenter);
2950 test_aggregation();
2951 test_interfaces();
2952 test_enum_pins();
2953 test_find_pin();
2954 test_pin_info();
2955 test_default_mixer();
2956 test_default_mixer_type_negotiation();
2957 test_surface_sample();
2958 test_default_presenter();
2959 test_MFCreateVideoMixerAndPresenter();
2960 test_MFCreateVideoSampleAllocator();
2961 test_presenter_video_position();
2962 test_presenter_native_video_size();
2963 test_presenter_ar_mode();
2964 test_presenter_video_window();
2965 test_presenter_quality_control();
2966 test_presenter_media_type();
2967 test_presenter_shutdown();
2968 test_mixer_output_rectangle();
2969 test_mixer_zorder();
2970 test_mixer_samples();
2971 test_MFIsFormatYUV();
2973 CoUninitialize();