evr/presenter: Add IMFGetService stub.
[wine.git] / dlls / evr / tests / evr.c
blobb59da51e475e4edbf4d3e8342358624e2249fe73
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[] = {'E','V','R',' ','I','n','p','u','t','0',0};
34 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **video_type);
36 static HWND create_window(void)
38 RECT r = {0, 0, 640, 480};
40 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
42 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
43 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
46 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
48 D3DPRESENT_PARAMETERS present_parameters = {0};
49 IDirect3DDevice9 *device = NULL;
51 present_parameters.BackBufferWidth = 640;
52 present_parameters.BackBufferHeight = 480;
53 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
54 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
55 present_parameters.hDeviceWindow = focus_window;
56 present_parameters.Windowed = TRUE;
57 present_parameters.EnableAutoDepthStencil = TRUE;
58 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
60 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
61 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
63 return device;
66 static IBaseFilter *create_evr(void)
68 IBaseFilter *filter = NULL;
69 HRESULT hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, NULL, CLSCTX_INPROC_SERVER,
70 &IID_IBaseFilter, (void **)&filter);
71 ok(hr == S_OK, "Got hr %#x.\n", hr);
72 return filter;
75 static ULONG get_refcount(void *iface)
77 IUnknown *unknown = iface;
78 IUnknown_AddRef(unknown);
79 return IUnknown_Release(unknown);
82 static const GUID test_iid = {0x33333333};
83 static LONG outer_ref = 1;
85 static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out)
87 if (IsEqualGUID(iid, &IID_IUnknown)
88 || IsEqualGUID(iid, &IID_IBaseFilter)
89 || IsEqualGUID(iid, &test_iid))
91 *out = (IUnknown *)0xdeadbeef;
92 return S_OK;
94 ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
95 return E_NOINTERFACE;
98 static ULONG WINAPI outer_AddRef(IUnknown *iface)
100 return InterlockedIncrement(&outer_ref);
103 static ULONG WINAPI outer_Release(IUnknown *iface)
105 return InterlockedDecrement(&outer_ref);
108 static const IUnknownVtbl outer_vtbl =
110 outer_QueryInterface,
111 outer_AddRef,
112 outer_Release,
115 static IUnknown test_outer = {&outer_vtbl};
117 static void test_aggregation(void)
119 IBaseFilter *filter, *filter2;
120 IMFVideoPresenter *presenter;
121 IUnknown *unk, *unk2;
122 IMFTransform *mixer;
123 HRESULT hr;
124 ULONG ref;
126 filter = (IBaseFilter *)0xdeadbeef;
127 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
128 &IID_IBaseFilter, (void **)&filter);
129 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
130 ok(!filter, "Got interface %p.\n", filter);
132 hr = CoCreateInstance(&CLSID_EnhancedVideoRenderer, &test_outer, CLSCTX_INPROC_SERVER,
133 &IID_IUnknown, (void **)&unk);
134 ok(hr == S_OK, "Got hr %#x.\n", hr);
135 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
136 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
137 ref = get_refcount(unk);
138 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
140 ref = IUnknown_AddRef(unk);
141 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
142 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
144 ref = IUnknown_Release(unk);
145 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
146 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
148 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
149 ok(hr == S_OK, "Got hr %#x.\n", hr);
150 ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2);
151 IUnknown_Release(unk2);
153 hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter);
154 ok(hr == S_OK, "Got hr %#x.\n", hr);
156 hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2);
157 ok(hr == S_OK, "Got hr %#x.\n", hr);
158 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
160 hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2);
161 ok(hr == S_OK, "Got hr %#x.\n", hr);
162 ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2);
164 hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2);
165 ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr);
166 ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
168 hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2);
169 ok(hr == S_OK, "Got hr %#x.\n", hr);
170 ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
172 IBaseFilter_Release(filter);
173 ref = IUnknown_Release(unk);
174 ok(!ref, "Got unexpected refcount %d.\n", ref);
175 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
177 /* Default presenter. */
178 presenter = (void *)0xdeadbeef;
179 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter,
180 (void **)&presenter);
181 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
182 ok(!presenter, "Got interface %p.\n", presenter);
184 hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
185 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Unexpected hr %#x.\n", hr);
186 if (SUCCEEDED(hr))
188 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
189 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
190 ref = get_refcount(unk);
191 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
193 IUnknown_Release(unk);
196 /* Default mixer. */
197 presenter = (void *)0xdeadbeef;
198 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
199 (void **)&mixer);
200 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
201 ok(!mixer, "Got interface %p.\n", mixer);
203 hr = CoCreateInstance(&CLSID_MFVideoMixer9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk);
204 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
205 ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
206 ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n");
207 ref = get_refcount(unk);
208 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
210 IUnknown_Release(unk);
213 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
214 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
216 IUnknown *iface = iface_ptr;
217 HRESULT hr, expected_hr;
218 IUnknown *unk;
220 expected_hr = supported ? S_OK : E_NOINTERFACE;
222 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
223 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
224 if (SUCCEEDED(hr))
225 IUnknown_Release(unk);
228 static void test_interfaces(void)
230 IBaseFilter *filter = create_evr();
231 ULONG ref;
233 todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, TRUE);
234 check_interface(filter, &IID_IBaseFilter, TRUE);
235 check_interface(filter, &IID_IMediaFilter, TRUE);
236 check_interface(filter, &IID_IMediaPosition, TRUE);
237 check_interface(filter, &IID_IMediaSeeking, TRUE);
238 check_interface(filter, &IID_IPersist, TRUE);
239 check_interface(filter, &IID_IUnknown, TRUE);
241 check_interface(filter, &IID_IBasicAudio, FALSE);
242 check_interface(filter, &IID_IBasicVideo, FALSE);
243 check_interface(filter, &IID_IDirectXVideoMemoryConfiguration, FALSE);
244 check_interface(filter, &IID_IMemInputPin, FALSE);
245 check_interface(filter, &IID_IPersistPropertyBag, FALSE);
246 check_interface(filter, &IID_IPin, FALSE);
247 check_interface(filter, &IID_IReferenceClock, FALSE);
248 check_interface(filter, &IID_IVideoWindow, FALSE);
250 ref = IBaseFilter_Release(filter);
251 ok(!ref, "Got unexpected refcount %d.\n", ref);
254 static void test_enum_pins(void)
256 IBaseFilter *filter = create_evr();
257 IEnumPins *enum1, *enum2;
258 ULONG count, ref;
259 IPin *pins[2];
260 HRESULT hr;
262 ref = get_refcount(filter);
263 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
265 hr = IBaseFilter_EnumPins(filter, NULL);
266 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
268 hr = IBaseFilter_EnumPins(filter, &enum1);
269 ok(hr == S_OK, "Got hr %#x.\n", hr);
270 ref = get_refcount(filter);
271 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
272 ref = get_refcount(enum1);
273 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
275 hr = IEnumPins_Next(enum1, 1, NULL, NULL);
276 ok(hr == E_POINTER, "Got hr %#x.\n", hr);
278 hr = IEnumPins_Next(enum1, 1, pins, NULL);
279 ok(hr == S_OK, "Got hr %#x.\n", hr);
280 ref = get_refcount(filter);
281 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
282 ref = get_refcount(pins[0]);
283 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
284 ref = get_refcount(enum1);
285 ok(ref == 1, "Got unexpected refcount %d.\n", ref);
286 IPin_Release(pins[0]);
287 ref = get_refcount(filter);
288 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
290 hr = IEnumPins_Next(enum1, 1, pins, NULL);
291 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
293 hr = IEnumPins_Reset(enum1);
294 ok(hr == S_OK, "Got hr %#x.\n", hr);
296 hr = IEnumPins_Next(enum1, 1, pins, &count);
297 ok(hr == S_OK, "Got hr %#x.\n", hr);
298 ok(count == 1, "Got count %u.\n", count);
299 IPin_Release(pins[0]);
301 hr = IEnumPins_Next(enum1, 1, pins, &count);
302 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
303 ok(!count, "Got count %u.\n", count);
305 hr = IEnumPins_Reset(enum1);
306 ok(hr == S_OK, "Got hr %#x.\n", hr);
308 hr = IEnumPins_Next(enum1, 2, pins, NULL);
309 ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
311 hr = IEnumPins_Next(enum1, 2, pins, &count);
312 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
313 ok(count == 1, "Got count %u.\n", count);
314 IPin_Release(pins[0]);
316 hr = IEnumPins_Reset(enum1);
317 ok(hr == S_OK, "Got hr %#x.\n", hr);
319 hr = IEnumPins_Clone(enum1, &enum2);
320 ok(hr == S_OK, "Got hr %#x.\n", hr);
322 hr = IEnumPins_Skip(enum1, 2);
323 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
325 hr = IEnumPins_Skip(enum1, 1);
326 ok(hr == S_OK, "Got hr %#x.\n", hr);
328 hr = IEnumPins_Skip(enum1, 1);
329 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
331 hr = IEnumPins_Next(enum1, 1, pins, NULL);
332 ok(hr == S_FALSE, "Got hr %#x.\n", hr);
334 hr = IEnumPins_Next(enum2, 1, pins, NULL);
335 ok(hr == S_OK, "Got hr %#x.\n", hr);
336 IPin_Release(pins[0]);
338 IEnumPins_Release(enum2);
339 IEnumPins_Release(enum1);
340 ref = IBaseFilter_Release(filter);
341 ok(!ref, "Got outstanding refcount %d.\n", ref);
344 static void test_find_pin(void)
346 IBaseFilter *filter = create_evr();
347 IEnumPins *enum_pins;
348 IPin *pin, *pin2;
349 HRESULT hr;
350 ULONG ref;
352 hr = IBaseFilter_EnumPins(filter, &enum_pins);
353 ok(hr == S_OK, "Got hr %#x.\n", hr);
355 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
356 ok(hr == S_OK, "Got hr %#x.\n", hr);
357 hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL);
358 ok(hr == S_OK, "Got hr %#x.\n", hr);
359 ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2);
360 IPin_Release(pin2);
361 IPin_Release(pin);
363 IEnumPins_Release(enum_pins);
364 ref = IBaseFilter_Release(filter);
365 ok(!ref, "Got outstanding refcount %d.\n", ref);
368 static void test_pin_info(void)
370 IBaseFilter *filter = create_evr();
371 PIN_DIRECTION dir;
372 PIN_INFO info;
373 HRESULT hr;
374 WCHAR *id;
375 ULONG ref;
376 IPin *pin;
378 hr = IBaseFilter_FindPin(filter, sink_id, &pin);
379 ok(hr == S_OK, "Got hr %#x.\n", hr);
380 ref = get_refcount(filter);
381 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
382 ref = get_refcount(pin);
383 ok(ref == 2, "Got unexpected refcount %d.\n", ref);
385 hr = IPin_QueryPinInfo(pin, &info);
386 ok(hr == S_OK, "Got hr %#x.\n", hr);
387 ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter);
388 ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir);
389 ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
390 ref = get_refcount(filter);
391 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
392 ref = get_refcount(pin);
393 ok(ref == 3, "Got unexpected refcount %d.\n", ref);
394 IBaseFilter_Release(info.pFilter);
396 hr = IPin_QueryDirection(pin, &dir);
397 ok(hr == S_OK, "Got hr %#x.\n", hr);
398 ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir);
400 hr = IPin_QueryId(pin, &id);
401 ok(hr == S_OK, "Got hr %#x.\n", hr);
402 ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id));
403 CoTaskMemFree(id);
405 hr = IPin_QueryInternalConnections(pin, NULL, NULL);
406 ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
408 IPin_Release(pin);
409 ref = IBaseFilter_Release(filter);
410 ok(!ref, "Got outstanding refcount %d.\n", ref);
413 static void test_default_mixer(void)
415 DWORD input_min, input_max, output_min, output_max;
416 IMFAttributes *attributes, *attributes2;
417 IMFVideoMixerControl2 *mixer_control2;
418 MFT_OUTPUT_STREAM_INFO output_info;
419 MFT_INPUT_STREAM_INFO input_info;
420 DWORD input_count, output_count;
421 IMFVideoProcessor *processor;
422 IMFVideoDeviceID *deviceid;
423 MFVideoNormalizedRect rect;
424 DWORD input_id, output_id;
425 IMFTransform *transform;
426 DXVA2_ValueRange range;
427 DXVA2_Fixed32 dxva_value;
428 DWORD flags, value, count;
429 IMFGetService *gs;
430 COLORREF color;
431 unsigned int i;
432 DWORD ids[16];
433 IUnknown *unk;
434 GUID *guids;
435 HRESULT hr;
436 IID iid;
438 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
439 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
441 hr = IMFTransform_QueryInterface(transform, &IID_IMFQualityAdvise, (void **)&unk);
442 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
443 IUnknown_Release(unk);
445 hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
446 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
447 IUnknown_Release(unk);
449 hr = IMFTransform_QueryInterface(transform, &IID_IMFGetService, (void **)&gs);
450 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
452 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerBitmap, (void **)&unk);
453 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
454 IUnknown_Release(unk);
456 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoProcessor, (void **)&processor);
457 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
459 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, (void **)&unk);
460 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
461 IUnknown_Release(unk);
463 if (SUCCEEDED(IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl2, (void **)&mixer_control2)))
465 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, NULL);
466 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
468 hr = IMFVideoMixerControl2_GetMixingPrefs(mixer_control2, &flags);
469 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
470 ok(!flags, "Unexpected flags %#x.\n", flags);
472 IMFVideoMixerControl2_Release(mixer_control2);
475 hr = IMFVideoProcessor_GetBackgroundColor(processor, NULL);
476 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
478 color = 1;
479 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
480 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
481 ok(!color, "Unexpected color %#x.\n", color);
483 hr = IMFVideoProcessor_SetBackgroundColor(processor, 0x00121212);
484 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
486 hr = IMFVideoProcessor_GetBackgroundColor(processor, &color);
487 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
488 ok(color == 0x121212, "Unexpected color %#x.\n", color);
490 hr = IMFVideoProcessor_GetFilteringRange(processor, DXVA2_DetailFilterChromaLevel, &range);
491 todo_wine
492 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
494 hr = IMFVideoProcessor_GetFilteringValue(processor, DXVA2_DetailFilterChromaLevel, &dxva_value);
495 todo_wine
496 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
498 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
499 todo_wine
500 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
502 IMFVideoProcessor_Release(processor);
504 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoPositionMapper, (void **)&unk);
505 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
506 IUnknown_Release(unk);
508 IMFGetService_Release(gs);
510 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoMixerBitmap, (void **)&unk);
511 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
512 IUnknown_Release(unk);
514 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoPositionMapper, (void **)&unk);
515 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
516 IUnknown_Release(unk);
518 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&unk);
519 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
520 IUnknown_Release(unk);
522 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoMixerControl, (void **)&unk);
523 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
524 IUnknown_Release(unk);
526 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid);
527 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
529 hr = IMFTransform_GetAttributes(transform, NULL);
530 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
532 hr = IMFTransform_GetAttributes(transform, &attributes);
533 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
535 hr = IMFTransform_GetAttributes(transform, &attributes2);
536 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
537 ok(attributes == attributes2, "Unexpected attributes instance.\n");
538 IMFAttributes_Release(attributes2);
540 hr = IMFTransform_QueryInterface(transform, &IID_IMFAttributes, (void **)&attributes2);
541 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
542 ok(attributes != attributes2, "Unexpected attributes instance.\n");
544 hr = IMFAttributes_QueryInterface(attributes2, &IID_IMFTransform, (void **)&unk);
545 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
546 IUnknown_Release(unk);
548 hr = IMFAttributes_GetCount(attributes2, &count);
549 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
550 ok(count == 1, "Unexpected attribute count %u.\n", count);
552 value = 0;
553 hr = IMFAttributes_GetUINT32(attributes2, &MF_SA_D3D_AWARE, &value);
554 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
555 ok(value == 1, "Unexpected value %d.\n", value);
557 IMFAttributes_Release(attributes2);
559 hr = IMFAttributes_GetCount(attributes, &count);
560 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
561 ok(count == 1, "Unexpected attribute count %u.\n", count);
563 memset(&rect, 0, sizeof(rect));
564 hr = IMFAttributes_GetBlob(attributes, &VIDEO_ZOOM_RECT, (UINT8 *)&rect, sizeof(rect), NULL);
565 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
566 ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f,
567 "Unexpected zoom rect (%f, %f) - (%f, %f).\n", rect.left, rect.top, rect.right, rect.bottom);
569 IMFAttributes_Release(attributes);
571 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
572 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
574 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
575 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
576 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
578 IMFVideoDeviceID_Release(deviceid);
580 /* Stream configuration. */
581 input_count = output_count = 0;
582 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
583 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
584 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
586 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
587 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
588 ok(input_min == 1 && input_max == 16 && output_min == 1 && output_max == 1, "Unexpected stream limits %u/%u, %u/%u.\n",
589 input_min, input_max, output_min, output_max);
591 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
592 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
594 hr = IMFTransform_GetOutputStreamInfo(transform, 1, &output_info);
595 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
597 memset(&input_info, 0xcc, sizeof(input_info));
598 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
599 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
601 memset(&output_info, 0xcc, sizeof(output_info));
602 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
603 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
604 ok(!(output_info.dwFlags & (MFT_OUTPUT_STREAM_PROVIDES_SAMPLES | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES)),
605 "Unexpected output flags %#x.\n", output_info.dwFlags);
607 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
608 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
609 ok(input_id == 0 && output_id == 0, "Unexpected stream ids.\n");
611 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
612 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
614 hr = IMFTransform_GetOutputStreamAttributes(transform, 1, &attributes);
615 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
617 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
618 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
620 hr = IMFTransform_AddInputStreams(transform, 16, NULL);
621 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
623 hr = IMFTransform_AddInputStreams(transform, 16, ids);
624 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
626 memset(ids, 0, sizeof(ids));
627 hr = IMFTransform_AddInputStreams(transform, 15, ids);
628 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
630 for (i = 0; i < ARRAY_SIZE(ids); ++i)
631 ids[i] = i + 1;
633 hr = IMFTransform_AddInputStreams(transform, 15, ids);
634 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
636 input_count = output_count = 0;
637 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
638 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
639 ok(input_count == 16 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
641 memset(&input_info, 0, sizeof(input_info));
642 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
643 ok(hr == S_OK, "Failed to get input info, hr %#x.\n", hr);
644 ok((input_info.dwFlags & (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL)) ==
645 (MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL), "Unexpected flags %#x.\n", input_info.dwFlags);
647 attributes = NULL;
648 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
649 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
650 ok(!!attributes, "Unexpected attributes.\n");
652 attributes2 = NULL;
653 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes2);
654 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
655 ok(attributes == attributes2, "Unexpected instance.\n");
657 IMFAttributes_Release(attributes2);
658 IMFAttributes_Release(attributes);
660 attributes = NULL;
661 hr = IMFTransform_GetInputStreamAttributes(transform, 1, &attributes);
662 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
663 ok(!!attributes, "Unexpected attributes.\n");
664 IMFAttributes_Release(attributes);
666 hr = IMFTransform_DeleteInputStream(transform, 0);
667 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
669 hr = IMFTransform_DeleteInputStream(transform, 1);
670 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
672 input_count = output_count = 0;
673 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
674 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
675 ok(input_count == 15 && output_count == 1, "Unexpected stream count %u/%u.\n", input_count, output_count);
677 IMFTransform_Release(transform);
679 hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
680 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
682 hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
683 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
684 IMFTransform_Release(transform);
687 static void test_surface_sample(void)
689 IDirect3DSurface9 *backbuffer = NULL;
690 IMFDesiredSample *desired_sample;
691 IMFMediaBuffer *buffer, *buffer2;
692 IDirect3DSwapChain9 *swapchain;
693 IDirect3DDevice9 *device;
694 DWORD count, length;
695 IMFSample *sample;
696 LONGLONG duration;
697 IDirect3D9 *d3d;
698 IUnknown *unk;
699 HWND window;
700 HRESULT hr;
701 BYTE *data;
703 window = create_window();
704 d3d = Direct3DCreate9(D3D_SDK_VERSION);
705 ok(!!d3d, "Failed to create a D3D object.\n");
706 if (!(device = create_device(d3d, window)))
708 skip("Failed to create a D3D device, skipping tests.\n");
709 goto done;
712 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
713 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
715 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
716 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
717 ok(backbuffer != NULL, "The back buffer is NULL\n");
719 IDirect3DSwapChain9_Release(swapchain);
721 hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample);
722 todo_wine
723 ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr);
724 if (FAILED(hr)) goto done;
726 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
727 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
728 IUnknown_Release(unk);
730 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&desired_sample);
731 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
733 hr = IMFSample_GetCount(sample, &count);
734 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
735 ok(!count, "Unexpected attribute count %u.\n", count);
737 IMFDesiredSample_SetDesiredSampleTimeAndDuration(desired_sample, 123, 456);
739 hr = IMFSample_GetCount(sample, &count);
740 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
741 ok(!count, "Unexpected attribute count %u.\n", count);
743 IMFDesiredSample_Release(desired_sample);
745 hr = IMFSample_GetCount(sample, &count);
746 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
747 ok(!count, "Unexpected attribute count.\n");
749 hr = IMFSample_GetBufferCount(sample, &count);
750 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
751 ok(count == 1, "Unexpected attribute count.\n");
753 hr = IMFSample_GetTotalLength(sample, &length);
754 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
755 ok(!length, "Unexpected length %u.\n", length);
757 hr = IMFSample_GetSampleDuration(sample, &duration);
758 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
760 hr = IMFSample_GetSampleTime(sample, &duration);
761 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
763 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
764 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
766 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
767 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
769 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
770 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
771 ok(!length, "Unexpected length %u.\n", length);
773 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
774 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
776 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk);
777 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
779 hr = IMFSample_AddBuffer(sample, buffer);
780 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
782 hr = IMFSample_GetBufferCount(sample, &count);
783 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
784 ok(count == 2, "Unexpected attribute count.\n");
786 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
787 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
789 hr = IMFSample_CopyToBuffer(sample, buffer);
790 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
792 hr = IMFSample_RemoveAllBuffers(sample);
793 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
795 hr = IMFSample_GetBufferCount(sample, &count);
796 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
797 ok(!count, "Unexpected attribute count.\n");
799 IMFMediaBuffer_Release(buffer);
801 IMFSample_Release(sample);
803 done:
804 if (backbuffer)
805 IDirect3DSurface9_Release(backbuffer);
806 IDirect3D9_Release(d3d);
807 DestroyWindow(window);
810 static void test_default_mixer_type_negotiation(void)
812 IMFMediaType *media_type, *media_type2;
813 IDirect3DDeviceManager9 *manager;
814 DXVA2_VideoProcessorCaps caps;
815 IMFVideoMediaType *video_type;
816 IMFVideoProcessor *processor;
817 IDirect3DDevice9 *device;
818 IMFTransform *transform;
819 GUID guid, *guids;
820 IDirect3D9 *d3d;
821 IUnknown *unk;
822 HWND window;
823 DWORD count;
824 HRESULT hr;
825 UINT token;
827 if (!pMFCreateVideoMediaTypeFromSubtype)
829 win_skip("Skipping mixer types tests.\n");
830 return;
833 hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
834 ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
836 hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
837 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
839 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
840 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
842 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
843 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
845 hr = MFCreateMediaType(&media_type);
846 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
848 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
849 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
851 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
852 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
854 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
855 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
857 /* Now try with device manager. */
859 window = create_window();
860 d3d = Direct3DCreate9(D3D_SDK_VERSION);
861 ok(!!d3d, "Failed to create a D3D object.\n");
862 if (!(device = create_device(d3d, window)))
864 skip("Failed to create a D3D device, skipping tests.\n");
865 goto done;
868 hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
869 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
871 hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
872 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
874 /* Now manager is not initialized. */
875 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
876 ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
878 hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
881 /* And now type description is incomplete. */
882 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
883 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
884 IMFMediaType_Release(media_type);
886 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB32, &video_type);
887 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
889 /* Partially initialized type. */
890 hr = IMFTransform_SetInputType(transform, 0, (IMFMediaType *)video_type, 0);
891 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
893 /* Only required data - frame size and uncompressed marker. */
894 hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
895 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
896 hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
897 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
899 hr = IMFTransform_SetInputType(transform, 0, (IMFMediaType *)video_type, 0);
900 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
902 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
903 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
904 ok(media_type != (IMFMediaType *)video_type, "Unexpected media type instance.\n");
906 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
907 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
908 ok(media_type == media_type2, "Unexpected media type instance.\n");
909 IMFMediaType_Release(media_type);
910 IMFMediaType_Release(media_type2);
912 hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoProcessor, (void **)&processor);
913 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
915 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
916 todo_wine
917 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
919 hr = IMFVideoProcessor_GetVideoProcessorCaps(processor, (GUID *)&DXVA2_VideoProcSoftwareDevice, &caps);
920 todo_wine
921 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
923 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
925 ok(media_type != (IMFMediaType *)video_type, "Unexpected pointer.\n");
926 hr = IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&unk);
927 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
928 IUnknown_Release(unk);
929 IMFMediaType_Release(media_type);
931 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
932 todo_wine
933 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
935 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
936 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
938 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
939 todo_wine
940 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
941 IMFMediaType_Release(media_type);
943 hr = IMFVideoProcessor_GetVideoProcessorMode(processor, &guid);
944 todo_wine
945 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
947 hr = IMFVideoProcessor_GetAvailableVideoProcessorModes(processor, &count, &guids);
948 todo_wine
949 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
950 if (SUCCEEDED(hr))
951 CoTaskMemFree(guids);
953 IMFVideoProcessor_Release(processor);
955 IMFVideoMediaType_Release(video_type);
957 IDirect3DDeviceManager9_Release(manager);
959 IDirect3DDevice9_Release(device);
961 done:
962 IMFTransform_Release(transform);
963 IDirect3D9_Release(d3d);
964 DestroyWindow(window);
967 static void test_default_presenter(void)
969 IMFVideoPresenter *presenter;
970 IMFRateSupport *rate_support;
971 IMFVideoDeviceID *deviceid;
972 IUnknown *unk;
973 float rate;
974 HRESULT hr;
975 GUID iid;
977 hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter);
978 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
980 hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter);
981 ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Failed to create default presenter, hr %#x.\n", hr);
982 if (FAILED(hr))
983 return;
985 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid);
986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
988 hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL);
989 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
991 hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid);
992 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
993 ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid));
995 IMFVideoDeviceID_Release(deviceid);
997 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
998 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
999 IUnknown_Release(unk);
1001 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&unk);
1002 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1003 IUnknown_Release(unk);
1005 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFGetService, (void **)&unk);
1006 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1007 IUnknown_Release(unk);
1009 /* Rate support. */
1010 hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
1011 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1013 rate = 1.0f;
1014 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
1015 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1016 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1018 rate = 1.0f;
1019 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
1020 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1021 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1023 rate = 1.0f;
1024 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
1025 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1026 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1028 rate = 1.0f;
1029 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
1030 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1031 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
1033 IMFRateSupport_Release(rate_support);
1035 IMFVideoPresenter_Release(presenter);
1038 static void test_MFCreateVideoMixerAndPresenter(void)
1040 IUnknown *mixer, *presenter;
1041 HRESULT hr;
1043 hr = MFCreateVideoMixerAndPresenter(NULL, NULL, &IID_IUnknown, (void **)&mixer, &IID_IUnknown, (void **)&presenter);
1044 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1046 IUnknown_Release(mixer);
1047 IUnknown_Release(presenter);
1050 static void test_MFCreateVideoSampleAllocator(void)
1052 IMFVideoSampleAllocatorCallback *allocator_cb;
1053 IMFVideoSampleAllocator *allocator;
1054 IMFVideoMediaType *video_type;
1055 IMFSample *sample, *sample2;
1056 IDirect3DSurface9 *surface;
1057 IMFMediaType *media_type;
1058 IMFMediaBuffer *buffer;
1059 IMFGetService *gs;
1060 IUnknown *unk;
1061 HRESULT hr;
1062 LONG count;
1064 hr = MFCreateVideoSampleAllocator(&IID_IUnknown, (void **)&unk);
1065 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1066 IUnknown_Release(unk);
1068 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocator, (void **)&allocator);
1069 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1071 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
1072 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1074 count = 10;
1075 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1076 todo_wine {
1077 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1078 ok(!count, "Unexpected count %d.\n", count);
1080 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
1081 todo_wine
1082 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1084 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1085 todo_wine
1086 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
1088 hr = MFCreateMediaType(&media_type);
1089 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1091 /* It expects IMFVideoMediaType. */
1092 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
1093 todo_wine
1094 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1096 hr = MFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB32, &video_type);
1097 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1099 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, (IMFMediaType *)video_type);
1100 todo_wine
1101 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
1103 /* Frame size is required. */
1104 hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
1105 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1106 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, (IMFMediaType *)video_type);
1107 todo_wine
1108 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1110 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1111 todo_wine {
1112 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1113 ok(count == 1, "Unexpected count %d.\n", count);
1115 sample = NULL;
1116 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
1117 todo_wine
1118 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1119 if (SUCCEEDED(hr))
1120 ok(get_refcount(sample) == 3, "Unexpected refcount %u.\n", get_refcount(sample));
1122 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
1123 todo_wine
1124 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
1126 /* Reinitialize with active sample. */
1127 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 4, (IMFMediaType *)video_type);
1128 todo_wine
1129 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1130 if (sample)
1131 ok(get_refcount(sample) == 3, "Unexpected refcount %u.\n", get_refcount(sample));
1133 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
1134 todo_wine {
1135 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1136 ok(count == 4, "Unexpected count %d.\n", count);
1138 if (sample)
1140 hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&unk);
1141 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1142 IUnknown_Release(unk);
1144 hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk);
1145 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1146 IUnknown_Release(unk);
1148 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1149 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1151 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
1152 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Win7 */, "Unexpected hr %#x.\n", hr);
1154 /* Device manager wasn't set, sample gets regular memory buffers. */
1155 if (SUCCEEDED(hr))
1157 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
1158 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
1159 IMFGetService_Release(gs);
1162 IMFMediaBuffer_Release(buffer);
1164 IMFSample_Release(sample);
1167 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
1169 IMFMediaType_Release(media_type);
1171 IMFVideoSampleAllocator_Release(allocator);
1173 hr = MFCreateVideoSampleAllocator(&IID_IMFVideoSampleAllocatorCallback, (void **)&unk);
1174 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1175 IUnknown_Release(unk);
1178 START_TEST(evr)
1180 CoInitialize(NULL);
1182 pMFCreateVideoMediaTypeFromSubtype = (void *)GetProcAddress(GetModuleHandleA("mfplat.dll"), "MFCreateVideoMediaTypeFromSubtype");
1184 test_aggregation();
1185 test_interfaces();
1186 test_enum_pins();
1187 test_find_pin();
1188 test_pin_info();
1189 test_default_mixer();
1190 test_default_mixer_type_negotiation();
1191 test_surface_sample();
1192 test_default_presenter();
1193 test_MFCreateVideoMixerAndPresenter();
1194 test_MFCreateVideoSampleAllocator();
1196 CoUninitialize();