mf/tests: Relax error code test for IsMediaTypeSupported() of SAR.
[wine.git] / dlls / mf / tests / mf.c
blob117e2d2e7853e18b924b1826deb75368432a0034
1 /*
2 * Unit tests for mf.dll.
4 * Copyright 2017 Nikolay Sivov
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 #include <stdarg.h>
22 #include <string.h>
23 #include <float.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
30 #include "initguid.h"
31 #include "ole2.h"
33 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
34 DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
35 DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
37 #undef INITGUID
38 #include <guiddef.h>
39 #include "mfapi.h"
40 #include "mferror.h"
41 #include "mfidl.h"
42 #include "initguid.h"
43 #include "uuids.h"
44 #include "mmdeviceapi.h"
45 #include "audioclient.h"
46 #include "evr.h"
48 #include "wine/test.h"
50 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
51 static void _expect_ref(IUnknown* obj, ULONG expected_refcount, int line)
53 ULONG refcount;
54 IUnknown_AddRef(obj);
55 refcount = IUnknown_Release(obj);
56 ok_(__FILE__, line)(refcount == expected_refcount, "Unexpected refcount %d, expected %d.\n", refcount,
57 expected_refcount);
60 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
61 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
63 IUnknown *iface = iface_ptr;
64 HRESULT hr, expected_hr;
65 IUnknown *unk;
67 expected_hr = supported ? S_OK : E_NOINTERFACE;
69 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
70 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
71 if (SUCCEEDED(hr))
72 IUnknown_Release(unk);
75 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
76 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
78 IUnknown *iface = iface_ptr;
79 HRESULT hr, expected_hr;
80 IUnknown *unk;
82 expected_hr = supported ? S_OK : E_NOINTERFACE;
84 hr = MFGetService(iface, service, iid, (void **)&unk);
85 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
86 if (SUCCEEDED(hr))
87 IUnknown_Release(unk);
90 static HWND create_window(void)
92 RECT r = {0, 0, 640, 480};
94 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
96 return CreateWindowA("static", "mf_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
97 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
100 static WCHAR *load_resource(const WCHAR *name)
102 static WCHAR pathW[MAX_PATH];
103 DWORD written;
104 HANDLE file;
105 HRSRC res;
106 void *ptr;
108 GetTempPathW(ARRAY_SIZE(pathW), pathW);
109 lstrcatW(pathW, name);
111 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
112 NULL, CREATE_ALWAYS, 0, 0);
113 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
114 wine_dbgstr_w(pathW), GetLastError());
116 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
117 ok(res != 0, "couldn't find resource\n");
118 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
119 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
120 &written, NULL);
121 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
122 "couldn't write resource\n" );
123 CloseHandle(file);
125 return pathW;
128 static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
130 if (IsEqualIID(riid, &IID_IUnknown))
132 *obj = iface;
133 IUnknown_AddRef(iface);
134 return S_OK;
137 *obj = NULL;
138 return E_NOINTERFACE;
141 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
143 return 2;
146 static ULONG WINAPI test_unk_Release(IUnknown *iface)
148 return 1;
151 static const IUnknownVtbl test_unk_vtbl =
153 test_unk_QueryInterface,
154 test_unk_AddRef,
155 test_unk_Release,
158 static void test_topology(void)
160 IMFMediaType *mediatype, *mediatype2, *mediatype3;
161 IMFCollection *collection, *collection2;
162 IUnknown test_unk2 = { &test_unk_vtbl };
163 IUnknown test_unk = { &test_unk_vtbl };
164 IMFTopologyNode *node, *node2, *node3;
165 IMFTopology *topology, *topology2;
166 MF_TOPOLOGY_TYPE node_type;
167 UINT32 count, index;
168 IUnknown *object;
169 WORD node_count;
170 DWORD size;
171 HRESULT hr;
172 TOPOID id;
174 hr = MFCreateTopology(NULL);
175 ok(hr == E_POINTER, "got %#x\n", hr);
177 hr = MFCreateTopology(&topology);
178 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
179 hr = IMFTopology_GetTopologyID(topology, &id);
180 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
181 ok(id == 1, "Unexpected id.\n");
183 hr = MFCreateTopology(&topology2);
184 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
185 hr = IMFTopology_GetTopologyID(topology2, &id);
186 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
187 ok(id == 2, "Unexpected id.\n");
189 IMFTopology_Release(topology);
191 hr = MFCreateTopology(&topology);
192 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
193 hr = IMFTopology_GetTopologyID(topology, &id);
194 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
195 ok(id == 3, "Unexpected id.\n");
197 IMFTopology_Release(topology2);
199 /* No attributes by default. */
200 for (node_type = MF_TOPOLOGY_OUTPUT_NODE; node_type < MF_TOPOLOGY_TEE_NODE; ++node_type)
202 hr = MFCreateTopologyNode(node_type, &node);
203 ok(hr == S_OK, "Failed to create a node for type %d, hr %#x.\n", node_type, hr);
204 hr = IMFTopologyNode_GetCount(node, &count);
205 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
206 ok(!count, "Unexpected attribute count %u.\n", count);
207 IMFTopologyNode_Release(node);
210 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, NULL);
211 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
213 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
214 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
216 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
217 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
219 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
220 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
221 ok(((id >> 32) == GetCurrentProcessId()) && !!(id & 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id));
223 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
224 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
226 hr = IMFTopology_GetNodeCount(topology, NULL);
227 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
229 hr = IMFTopology_AddNode(topology, NULL);
230 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
232 node_count = 1;
233 hr = IMFTopology_GetNodeCount(topology, &node_count);
234 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
235 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
237 /* Same id, different nodes. */
238 hr = IMFTopology_AddNode(topology, node);
239 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
241 node_count = 0;
242 hr = IMFTopology_GetNodeCount(topology, &node_count);
243 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
244 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
246 hr = IMFTopology_AddNode(topology, node2);
247 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
248 IMFTopologyNode_Release(node2);
250 hr = IMFTopology_GetNodeByID(topology, id, &node2);
251 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
252 ok(node2 == node, "Unexpected node.\n");
253 IMFTopologyNode_Release(node2);
255 /* Change node id, add it again. */
256 hr = IMFTopologyNode_SetTopoNodeID(node, ++id);
257 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
259 hr = IMFTopology_GetNodeByID(topology, id, &node2);
260 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
261 ok(node2 == node, "Unexpected node.\n");
262 IMFTopologyNode_Release(node2);
264 hr = IMFTopology_GetNodeByID(topology, id + 1, &node2);
265 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
267 hr = IMFTopology_AddNode(topology, node);
268 ok(hr == E_INVALIDARG, "Failed to add a node, hr %#x.\n", hr);
270 hr = IMFTopology_GetNode(topology, 0, &node2);
271 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
272 ok(node2 == node, "Unexpected node.\n");
273 IMFTopologyNode_Release(node2);
275 hr = IMFTopology_GetNode(topology, 1, NULL);
276 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
278 hr = IMFTopology_GetNode(topology, 1, &node2);
279 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
281 hr = IMFTopology_GetNode(topology, -2, &node2);
282 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
284 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
285 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
286 hr = IMFTopology_AddNode(topology, node2);
287 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
288 IMFTopologyNode_Release(node2);
290 node_count = 0;
291 hr = IMFTopology_GetNodeCount(topology, &node_count);
292 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
293 ok(node_count == 2, "Unexpected node count %u.\n", node_count);
295 /* Remove with detached node, existing id. */
296 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
297 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
298 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
299 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
300 hr = IMFTopology_RemoveNode(topology, node2);
301 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
302 IMFTopologyNode_Release(node2);
304 hr = IMFTopology_RemoveNode(topology, node);
305 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
307 node_count = 0;
308 hr = IMFTopology_GetNodeCount(topology, &node_count);
309 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
310 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
312 hr = IMFTopology_Clear(topology);
313 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
315 node_count = 1;
316 hr = IMFTopology_GetNodeCount(topology, &node_count);
317 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
318 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
320 hr = IMFTopology_Clear(topology);
321 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
323 hr = IMFTopologyNode_SetTopoNodeID(node, 123);
324 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
326 IMFTopologyNode_Release(node);
328 /* Change id for attached node. */
329 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
330 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
332 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
333 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
335 hr = IMFTopology_AddNode(topology, node);
336 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
338 hr = IMFTopology_AddNode(topology, node2);
339 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
341 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
342 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
344 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
345 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
347 hr = IMFTopology_GetNodeByID(topology, id, &node3);
348 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
349 ok(node3 == node, "Unexpected node.\n");
350 IMFTopologyNode_Release(node3);
352 IMFTopologyNode_Release(node);
353 IMFTopologyNode_Release(node2);
355 /* Source/output collections. */
356 hr = IMFTopology_Clear(topology);
357 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
359 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
360 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
362 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
363 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
364 ok(!!collection, "Unexpected object pointer.\n");
366 hr = IMFTopology_GetSourceNodeCollection(topology, &collection2);
367 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
368 ok(!!collection2, "Unexpected object pointer.\n");
369 ok(collection2 != collection, "Expected cloned collection.\n");
371 hr = IMFCollection_GetElementCount(collection, &size);
372 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
373 ok(!size, "Unexpected item count.\n");
375 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
376 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
378 hr = IMFCollection_GetElementCount(collection, &size);
379 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
380 ok(size == 1, "Unexpected item count.\n");
382 hr = IMFCollection_GetElementCount(collection2, &size);
383 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
384 ok(!size, "Unexpected item count.\n");
386 IMFCollection_Release(collection2);
387 IMFCollection_Release(collection);
389 /* Add some nodes. */
390 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
391 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
393 hr = IMFTopology_GetOutputNodeCollection(topology, NULL);
394 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
396 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
397 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
398 hr = IMFTopology_AddNode(topology, node);
399 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
400 IMFTopologyNode_Release(node);
402 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
403 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
404 ok(!!collection, "Unexpected object pointer.\n");
405 hr = IMFCollection_GetElementCount(collection, &size);
406 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
407 ok(size == 1, "Unexpected item count.\n");
408 IMFCollection_Release(collection);
410 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
411 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
412 hr = IMFTopology_AddNode(topology, node);
413 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
414 IMFTopologyNode_Release(node);
416 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
417 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
418 ok(!!collection, "Unexpected object pointer.\n");
419 hr = IMFCollection_GetElementCount(collection, &size);
420 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
421 ok(size == 1, "Unexpected item count.\n");
422 IMFCollection_Release(collection);
424 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
425 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
426 hr = IMFTopology_AddNode(topology, node);
427 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
428 IMFTopologyNode_Release(node);
430 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
431 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
432 ok(!!collection, "Unexpected object pointer.\n");
433 hr = IMFCollection_GetElementCount(collection, &size);
434 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
435 ok(size == 1, "Unexpected item count.\n");
436 IMFCollection_Release(collection);
438 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
439 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
440 hr = IMFTopology_AddNode(topology, node);
441 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
443 /* Associated object. */
444 hr = IMFTopologyNode_SetObject(node, NULL);
445 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
447 hr = IMFTopologyNode_GetObject(node, NULL);
448 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
450 object = (void *)0xdeadbeef;
451 hr = IMFTopologyNode_GetObject(node, &object);
452 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
453 ok(!object, "Unexpected object %p.\n", object);
455 hr = IMFTopologyNode_SetObject(node, &test_unk);
456 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
458 hr = IMFTopologyNode_GetObject(node, &object);
459 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
460 ok(object == &test_unk, "Unexpected object %p.\n", object);
461 IUnknown_Release(object);
463 hr = IMFTopologyNode_SetObject(node, &test_unk2);
464 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
466 hr = IMFTopologyNode_GetCount(node, &count);
467 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
468 ok(count == 0, "Unexpected attribute count %u.\n", count);
470 hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &MF_TOPONODE_TRANSFORM_OBJECTID);
471 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
473 hr = IMFTopologyNode_SetObject(node, NULL);
474 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
476 object = (void *)0xdeadbeef;
477 hr = IMFTopologyNode_GetObject(node, &object);
478 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
479 ok(!object, "Unexpected object %p.\n", object);
481 hr = IMFTopologyNode_GetCount(node, &count);
482 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
483 ok(count == 1, "Unexpected attribute count %u.\n", count);
485 /* Preferred stream types. */
486 hr = IMFTopologyNode_GetInputCount(node, &count);
487 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
488 ok(count == 0, "Unexpected count %u.\n", count);
490 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype);
491 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
493 hr = MFCreateMediaType(&mediatype);
494 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
496 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
497 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
499 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
500 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
501 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
502 IMFMediaType_Release(mediatype2);
504 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
505 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
507 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
508 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
509 ok(!mediatype2, "Unexpected mediatype instance.\n");
511 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
512 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
514 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
515 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
517 hr = IMFTopologyNode_GetInputCount(node, &count);
518 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
519 ok(count == 2, "Unexpected count %u.\n", count);
521 hr = IMFTopologyNode_GetOutputCount(node, &count);
522 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
523 ok(count == 0, "Unexpected count %u.\n", count);
525 hr = IMFTopologyNode_SetOutputPrefType(node, 0, mediatype);
526 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
528 IMFTopologyNode_Release(node);
530 /* Source node. */
531 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
532 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
534 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
535 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
537 hr = IMFTopologyNode_SetOutputPrefType(node, 2, mediatype);
538 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
540 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
541 ok(hr == E_FAIL, "Failed to get preferred type, hr %#x.\n", hr);
542 ok(!mediatype2, "Unexpected mediatype instance.\n");
544 hr = IMFTopologyNode_GetOutputCount(node, &count);
545 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
546 ok(count == 3, "Unexpected count %u.\n", count);
548 IMFTopologyNode_Release(node);
550 /* Tee node. */
551 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
552 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
554 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
555 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
557 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
558 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
559 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
560 IMFMediaType_Release(mediatype2);
562 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
563 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
565 hr = IMFTopologyNode_GetInputCount(node, &count);
566 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
567 ok(count == 0, "Unexpected count %u.\n", count);
569 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
570 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
572 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
573 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
575 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype);
576 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
578 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
579 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
581 hr = MFCreateMediaType(&mediatype2);
582 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
584 /* Changing output type does not change input type. */
585 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype2);
586 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
588 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype3);
589 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
590 ok(mediatype3 == mediatype, "Unexpected mediatype instance.\n");
591 IMFMediaType_Release(mediatype3);
593 IMFMediaType_Release(mediatype2);
595 hr = IMFTopologyNode_GetInputCount(node, &count);
596 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
597 ok(count == 0, "Unexpected count %u.\n", count);
599 hr = IMFTopologyNode_GetOutputCount(node, &count);
600 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
601 ok(count == 5, "Unexpected count %u.\n", count);
603 IMFTopologyNode_Release(node);
605 /* Transform node. */
606 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
607 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
609 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
610 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
612 hr = IMFTopologyNode_GetInputCount(node, &count);
613 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
614 ok(count == 4, "Unexpected count %u.\n", count);
616 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype);
617 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
619 hr = IMFTopologyNode_GetInputCount(node, &count);
620 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
621 ok(count == 4, "Unexpected count %u.\n", count);
623 hr = IMFTopologyNode_GetOutputCount(node, &count);
624 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
625 ok(count == 5, "Unexpected count %u.\n", count);
627 IMFTopologyNode_Release(node);
629 IMFMediaType_Release(mediatype);
631 hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
632 ok(hr == S_OK || broken(hr == E_FAIL) /* before Win8 */, "Failed to get output node collection, hr %#x.\n", hr);
633 if (SUCCEEDED(hr))
635 ok(!!collection, "Unexpected object pointer.\n");
636 hr = IMFCollection_GetElementCount(collection, &size);
637 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
638 ok(size == 1, "Unexpected item count.\n");
639 IMFCollection_Release(collection);
642 IMFTopology_Release(topology);
644 /* Connect nodes. */
645 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
646 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
648 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
649 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
651 EXPECT_REF(node, 1);
652 EXPECT_REF(node2, 1);
654 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
655 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
657 EXPECT_REF(node, 2);
658 EXPECT_REF(node2, 2);
660 IMFTopologyNode_Release(node);
662 EXPECT_REF(node, 1);
663 EXPECT_REF(node2, 2);
665 IMFTopologyNode_Release(node2);
667 EXPECT_REF(node, 1);
668 EXPECT_REF(node2, 1);
670 hr = IMFTopologyNode_GetNodeType(node2, &node_type);
671 ok(hr == S_OK, "Failed to get node type, hr %#x.\n", hr);
673 IMFTopologyNode_Release(node);
675 /* Connect within topology. */
676 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
677 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
679 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
680 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
682 hr = MFCreateTopology(&topology);
683 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
685 hr = IMFTopology_AddNode(topology, node);
686 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
688 hr = IMFTopology_AddNode(topology, node2);
689 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
691 EXPECT_REF(node, 2);
692 EXPECT_REF(node2, 2);
694 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
695 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
697 EXPECT_REF(node, 3);
698 EXPECT_REF(node2, 3);
700 hr = IMFTopology_Clear(topology);
701 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
703 EXPECT_REF(node, 1);
704 EXPECT_REF(node2, 1);
706 /* Removing connected node breaks connection. */
707 hr = IMFTopology_AddNode(topology, node);
708 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
710 hr = IMFTopology_AddNode(topology, node2);
711 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
713 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
714 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
716 hr = IMFTopology_RemoveNode(topology, node);
717 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
719 EXPECT_REF(node, 1);
720 EXPECT_REF(node2, 2);
722 hr = IMFTopologyNode_GetOutput(node, 0, &node3, &index);
723 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
725 hr = IMFTopology_AddNode(topology, node);
726 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
728 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
729 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
731 hr = IMFTopology_RemoveNode(topology, node2);
732 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
734 EXPECT_REF(node, 2);
735 EXPECT_REF(node2, 1);
737 IMFTopologyNode_Release(node);
738 IMFTopologyNode_Release(node2);
740 /* Cloning nodes of different types. */
741 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
742 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
744 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
745 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
747 hr = IMFTopologyNode_CloneFrom(node, node2);
748 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
750 IMFTopologyNode_Release(node2);
752 /* Cloning preferred types. */
753 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
754 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
756 hr = MFCreateMediaType(&mediatype);
757 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
759 hr = IMFTopologyNode_SetOutputPrefType(node2, 0, mediatype);
760 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
762 /* Vista checks for additional attributes. */
763 hr = IMFTopologyNode_CloneFrom(node, node2);
764 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
766 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
767 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
768 ok(mediatype == mediatype2, "Unexpected media type.\n");
770 IMFMediaType_Release(mediatype2);
771 IMFMediaType_Release(mediatype);
773 IMFTopologyNode_Release(node2);
775 /* Existing preferred types are not cleared. */
776 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
777 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
779 hr = IMFTopologyNode_GetOutputCount(node, &count);
780 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
781 ok(count == 1, "Unexpected output count.\n");
783 hr = IMFTopologyNode_CloneFrom(node, node2);
784 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
786 hr = IMFTopologyNode_GetOutputCount(node, &count);
787 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
788 ok(count == 1, "Unexpected output count.\n");
790 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
791 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
792 ok(!!mediatype2, "Unexpected media type.\n");
793 IMFMediaType_Release(mediatype2);
795 hr = IMFTopologyNode_CloneFrom(node2, node);
796 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
798 hr = IMFTopologyNode_GetOutputCount(node2, &count);
799 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
800 ok(count == 1, "Unexpected output count.\n");
802 IMFTopologyNode_Release(node2);
803 IMFTopologyNode_Release(node);
805 /* Add one node, connect to another that hasn't been added. */
806 hr = IMFTopology_Clear(topology);
807 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
809 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
810 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
812 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
813 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
815 hr = IMFTopology_AddNode(topology, node);
816 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
818 hr = IMFTopology_GetNodeCount(topology, &node_count);
819 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
820 ok(node_count == 1, "Unexpected node count.\n");
822 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 0);
823 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
825 hr = IMFTopology_GetNodeCount(topology, &node_count);
826 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
827 ok(node_count == 1, "Unexpected node count.\n");
829 IMFTopologyNode_Release(node);
830 IMFTopologyNode_Release(node2);
832 /* Add same node to different topologies. */
833 hr = IMFTopology_Clear(topology);
834 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
836 hr = MFCreateTopology(&topology2);
837 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
839 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
840 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
842 hr = IMFTopology_AddNode(topology, node);
843 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
844 EXPECT_REF(node, 2);
846 hr = IMFTopology_GetNodeCount(topology, &node_count);
847 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
848 ok(node_count == 1, "Unexpected node count.\n");
850 hr = IMFTopology_GetNodeCount(topology2, &node_count);
851 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
852 ok(node_count == 0, "Unexpected node count.\n");
854 hr = IMFTopology_AddNode(topology2, node);
855 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
856 EXPECT_REF(node, 3);
858 hr = IMFTopology_GetNodeCount(topology, &node_count);
859 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
860 ok(node_count == 1, "Unexpected node count.\n");
862 hr = IMFTopology_GetNodeCount(topology2, &node_count);
863 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
864 ok(node_count == 1, "Unexpected node count.\n");
866 IMFTopology_Release(topology2);
867 IMFTopology_Release(topology);
870 static void test_topology_tee_node(void)
872 IMFTopologyNode *src_node, *tee_node;
873 IMFMediaType *mediatype, *mediatype2;
874 IMFTopology *topology;
875 unsigned int count;
876 HRESULT hr;
878 hr = MFCreateTopology(&topology);
879 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
881 hr = MFCreateMediaType(&mediatype);
882 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
884 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &tee_node);
885 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
887 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
888 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
890 hr = IMFTopologyNode_SetInputPrefType(tee_node, 0, mediatype);
891 ok(hr == S_OK, "Failed to set type, hr %#x.\n", hr);
893 /* Even though tee node has only one input and source has only one output,
894 it's possible to connect to higher inputs/outputs. */
896 /* SRC(0) -> TEE(0) */
897 hr = IMFTopologyNode_ConnectOutput(src_node, 0, tee_node, 0);
898 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
900 hr = IMFTopologyNode_GetInputCount(tee_node, &count);
901 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
902 ok(count == 1, "Unexpected count %u.\n", count);
904 hr = IMFTopologyNode_GetInputPrefType(tee_node, 0, &mediatype2);
905 ok(hr == S_OK, "Failed to get type, hr %#x.\n", hr);
906 ok(mediatype2 == mediatype, "Unexpected type.\n");
907 IMFMediaType_Release(mediatype2);
909 /* SRC(0) -> TEE(1) */
910 hr = IMFTopologyNode_ConnectOutput(src_node, 0, tee_node, 1);
911 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
913 hr = IMFTopologyNode_GetInputCount(tee_node, &count);
914 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
915 ok(count == 2, "Unexpected count %u.\n", count);
917 hr = IMFTopologyNode_SetInputPrefType(tee_node, 1, mediatype);
918 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
920 /* SRC(1) -> TEE(1) */
921 hr = IMFTopologyNode_ConnectOutput(src_node, 1, tee_node, 1);
922 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
924 hr = IMFTopologyNode_GetOutputCount(src_node, &count);
925 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
926 ok(count == 2, "Unexpected count %u.\n", count);
928 IMFMediaType_Release(mediatype);
929 IMFTopologyNode_Release(src_node);
930 IMFTopologyNode_Release(tee_node);
931 IMFTopology_Release(topology);
934 static HRESULT WINAPI test_getservice_QI(IMFGetService *iface, REFIID riid, void **obj)
936 if (IsEqualIID(riid, &IID_IMFGetService) || IsEqualIID(riid, &IID_IUnknown))
938 *obj = iface;
939 return S_OK;
942 *obj = NULL;
943 return E_NOINTERFACE;
946 static ULONG WINAPI test_getservice_AddRef(IMFGetService *iface)
948 return 2;
951 static ULONG WINAPI test_getservice_Release(IMFGetService *iface)
953 return 1;
956 static HRESULT WINAPI test_getservice_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
958 *obj = (void *)0xdeadbeef;
959 return 0x83eddead;
962 static const IMFGetServiceVtbl testmfgetservicevtbl =
964 test_getservice_QI,
965 test_getservice_AddRef,
966 test_getservice_Release,
967 test_getservice_GetService,
970 static IMFGetService test_getservice = { &testmfgetservicevtbl };
972 static HRESULT WINAPI testservice_QI(IUnknown *iface, REFIID riid, void **obj)
974 if (IsEqualIID(riid, &IID_IUnknown))
976 *obj = iface;
977 return S_OK;
980 *obj = NULL;
982 if (IsEqualIID(riid, &IID_IMFGetService))
983 return 0x82eddead;
985 return E_NOINTERFACE;
988 static HRESULT WINAPI testservice2_QI(IUnknown *iface, REFIID riid, void **obj)
990 if (IsEqualIID(riid, &IID_IUnknown))
992 *obj = iface;
993 return S_OK;
996 if (IsEqualIID(riid, &IID_IMFGetService))
998 *obj = &test_getservice;
999 return S_OK;
1002 *obj = NULL;
1003 return E_NOINTERFACE;
1006 static ULONG WINAPI testservice_AddRef(IUnknown *iface)
1008 return 2;
1011 static ULONG WINAPI testservice_Release(IUnknown *iface)
1013 return 1;
1016 static const IUnknownVtbl testservicevtbl =
1018 testservice_QI,
1019 testservice_AddRef,
1020 testservice_Release,
1023 static const IUnknownVtbl testservice2vtbl =
1025 testservice2_QI,
1026 testservice_AddRef,
1027 testservice_Release,
1030 static IUnknown testservice = { &testservicevtbl };
1031 static IUnknown testservice2 = { &testservice2vtbl };
1033 static void test_MFGetService(void)
1035 IUnknown *unk;
1036 HRESULT hr;
1038 hr = MFGetService(NULL, NULL, NULL, NULL);
1039 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
1041 unk = (void *)0xdeadbeef;
1042 hr = MFGetService(NULL, NULL, NULL, (void **)&unk);
1043 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
1044 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1046 hr = MFGetService(&testservice, NULL, NULL, NULL);
1047 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
1049 unk = (void *)0xdeadbeef;
1050 hr = MFGetService(&testservice, NULL, NULL, (void **)&unk);
1051 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
1052 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1054 unk = NULL;
1055 hr = MFGetService(&testservice2, NULL, NULL, (void **)&unk);
1056 ok(hr == 0x83eddead, "Unexpected return value %#x.\n", hr);
1057 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1060 static void test_sequencer_source(void)
1062 IMFSequencerSource *seq_source;
1063 HRESULT hr;
1065 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1066 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1068 hr = MFCreateSequencerSource(NULL, &seq_source);
1069 ok(hr == S_OK, "Failed to create sequencer source, hr %#x.\n", hr);
1071 check_interface(seq_source, &IID_IMFMediaSourceTopologyProvider, TRUE);
1073 IMFSequencerSource_Release(seq_source);
1075 hr = MFShutdown();
1076 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1079 struct test_callback
1081 IMFAsyncCallback IMFAsyncCallback_iface;
1084 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
1086 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
1087 IsEqualIID(riid, &IID_IUnknown))
1089 *obj = iface;
1090 IMFAsyncCallback_AddRef(iface);
1091 return S_OK;
1094 *obj = NULL;
1095 return E_NOINTERFACE;
1098 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
1100 return 2;
1103 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
1105 return 1;
1108 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
1110 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
1111 return E_NOTIMPL;
1114 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
1116 ok(result != NULL, "Unexpected result object.\n");
1118 return E_NOTIMPL;
1121 static const IMFAsyncCallbackVtbl testcallbackvtbl =
1123 testcallback_QueryInterface,
1124 testcallback_AddRef,
1125 testcallback_Release,
1126 testcallback_GetParameters,
1127 testcallback_Invoke,
1130 static void init_test_callback(struct test_callback *callback)
1132 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
1135 static void test_session_events(IMFMediaSession *session)
1137 struct test_callback callback, callback2;
1138 IMFAsyncResult *result;
1139 IMFMediaEvent *event;
1140 HRESULT hr;
1142 init_test_callback(&callback);
1143 init_test_callback(&callback2);
1145 hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event);
1146 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
1148 /* Async case. */
1149 hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL);
1150 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1152 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
1153 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
1155 /* Same callback, same state. */
1156 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
1157 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
1159 /* Same callback, different state. */
1160 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
1161 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
1163 /* Different callback, same state. */
1164 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session);
1165 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
1167 /* Different callback, different state. */
1168 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
1169 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
1171 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
1172 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
1174 hr = IMFMediaSession_EndGetEvent(session, result, &event);
1175 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
1177 /* Shutdown behavior. */
1178 hr = IMFMediaSession_Shutdown(session);
1179 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1182 static void test_media_session(void)
1184 IMFRateControl *rate_control, *rate_control2;
1185 IMFLocalMFTRegistration *local_reg;
1186 MFCLOCK_PROPERTIES clock_props;
1187 IMFRateSupport *rate_support;
1188 IMFAttributes *attributes;
1189 IMFMediaSession *session;
1190 IMFTopology *topology;
1191 IMFShutdown *shutdown;
1192 PROPVARIANT propvar;
1193 DWORD status, caps;
1194 IMFGetService *gs;
1195 IMFClock *clock;
1196 IUnknown *unk;
1197 HRESULT hr;
1198 float rate;
1199 BOOL thin;
1201 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1202 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1204 hr = MFCreateMediaSession(NULL, &session);
1205 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1207 hr = IMFMediaSession_QueryInterface(session, &IID_IMFAttributes, (void **)&unk);
1208 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1210 hr = IMFMediaSession_QueryInterface(session, &IID_IMFGetService, (void **)&gs);
1211 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
1213 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support);
1214 ok(hr == S_OK, "Failed to get rate support interface, hr %#x.\n", hr);
1216 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, (void **)&rate_control);
1217 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
1219 hr = IMFGetService_GetService(gs, &MF_LOCAL_MFT_REGISTRATION_SERVICE, &IID_IMFLocalMFTRegistration,
1220 (void **)&local_reg);
1221 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get registration service, hr %#x.\n", hr);
1222 if (SUCCEEDED(hr))
1223 IMFLocalMFTRegistration_Release(local_reg);
1225 hr = IMFRateSupport_QueryInterface(rate_support, &IID_IMFMediaSession, (void **)&unk);
1226 ok(hr == S_OK, "Failed to get session interface, hr %#x.\n", hr);
1227 ok(unk == (IUnknown *)session, "Unexpected pointer.\n");
1228 IUnknown_Release(unk);
1230 hr = IMFRateControl_GetRate(rate_control, NULL, NULL);
1231 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1233 rate = 0.0f;
1234 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
1235 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1236 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1238 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
1239 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1241 thin = TRUE;
1242 rate = 0.0f;
1243 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1244 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1245 ok(!thin, "Unexpected thinning.\n");
1246 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1248 hr = IMFMediaSession_GetClock(session, &clock);
1249 ok(hr == S_OK, "Failed to get clock, hr %#x.\n", hr);
1251 hr = IMFClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control2);
1252 ok(hr == S_OK, "Failed to get rate control, hr %#x.\n", hr);
1254 rate = 0.0f;
1255 hr = IMFRateControl_GetRate(rate_control2, NULL, &rate);
1256 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1257 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1259 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.5f);
1260 todo_wine
1261 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
1263 IMFRateControl_Release(rate_control2);
1265 hr = IMFClock_GetProperties(clock, &clock_props);
1266 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1267 IMFClock_Release(clock);
1269 IMFRateControl_Release(rate_control);
1270 IMFRateSupport_Release(rate_support);
1272 IMFGetService_Release(gs);
1274 IMFMediaSession_Release(session);
1276 hr = MFCreateMediaSession(NULL, &session);
1277 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1279 hr = IMFMediaSession_GetClock(session, &clock);
1280 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1282 hr = IMFClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
1283 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1285 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1286 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1288 hr = IMFMediaSession_Shutdown(session);
1289 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1291 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1292 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1293 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
1295 IMFShutdown_Release(shutdown);
1297 hr = IMFMediaSession_ClearTopologies(session);
1298 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1300 hr = IMFMediaSession_Start(session, &GUID_NULL, NULL);
1301 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1303 propvar.vt = VT_EMPTY;
1304 hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar);
1305 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1307 hr = IMFMediaSession_Pause(session);
1308 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1310 hr = IMFMediaSession_Stop(session);
1311 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1313 hr = IMFMediaSession_Close(session);
1314 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1316 hr = IMFMediaSession_GetClock(session, &clock);
1317 ok(hr == MF_E_SHUTDOWN || broken(hr == E_UNEXPECTED) /* Win7 */, "Unexpected hr %#x.\n", hr);
1319 hr = IMFMediaSession_GetSessionCapabilities(session, &caps);
1320 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1322 hr = IMFMediaSession_GetSessionCapabilities(session, NULL);
1323 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1325 hr = IMFMediaSession_GetFullTopology(session, MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology);
1326 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1328 hr = IMFMediaSession_Shutdown(session);
1329 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1331 IMFMediaSession_Release(session);
1333 /* Custom topology loader, GUID is not registered. */
1334 hr = MFCreateAttributes(&attributes, 1);
1335 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
1337 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_TOPOLOADER, &MF_SESSION_TOPOLOADER);
1338 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1340 hr = MFCreateMediaSession(attributes, &session);
1341 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1342 IMFMediaSession_Release(session);
1344 /* Disabled quality manager. */
1345 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_QUALITY_MANAGER, &GUID_NULL);
1346 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1348 hr = MFCreateMediaSession(attributes, &session);
1349 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1350 IMFMediaSession_Release(session);
1352 IMFAttributes_Release(attributes);
1354 /* Basic events behavior. */
1355 hr = MFCreateMediaSession(NULL, &session);
1356 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1358 test_session_events(session);
1360 IMFMediaSession_Release(session);
1362 hr = MFShutdown();
1363 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1366 static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid,
1367 void **obj)
1369 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
1370 IsEqualIID(riid, &IID_IMFClockStateSink) ||
1371 IsEqualIID(riid, &IID_IUnknown))
1373 *obj = iface;
1374 IMFSampleGrabberSinkCallback_AddRef(iface);
1375 return S_OK;
1378 *obj = NULL;
1379 return E_NOINTERFACE;
1382 static ULONG WINAPI test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
1384 return 2;
1387 static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
1389 return 1;
1392 static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME systime,
1393 LONGLONG offset)
1395 return E_NOTIMPL;
1398 static HRESULT WINAPI test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1400 return E_NOTIMPL;
1403 static HRESULT WINAPI test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1405 return E_NOTIMPL;
1408 static HRESULT WINAPI test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1410 return E_NOTIMPL;
1413 static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME systime, float rate)
1415 return E_NOTIMPL;
1418 static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
1419 IMFPresentationClock *clock)
1421 return E_NOTIMPL;
1424 static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
1425 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
1427 return E_NOTIMPL;
1430 static HRESULT WINAPI test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
1432 return E_NOTIMPL;
1435 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl =
1437 test_grabber_callback_QueryInterface,
1438 test_grabber_callback_AddRef,
1439 test_grabber_callback_Release,
1440 test_grabber_callback_OnClockStart,
1441 test_grabber_callback_OnClockStop,
1442 test_grabber_callback_OnClockPause,
1443 test_grabber_callback_OnClockRestart,
1444 test_grabber_callback_OnClockSetRate,
1445 test_grabber_callback_OnSetPresentationClock,
1446 test_grabber_callback_OnProcessSample,
1447 test_grabber_callback_OnShutdown,
1450 static void test_topology_loader(void)
1452 IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl };
1453 IMFTopology *topology, *topology2, *full_topology;
1454 IMFTopologyNode *src_node, *sink_node;
1455 IMFPresentationDescriptor *pd;
1456 IMFSourceResolver *resolver;
1457 IMFActivate *sink_activate;
1458 IMFStreamSink *stream_sink;
1459 unsigned int count, value;
1460 IMFMediaType *media_type;
1461 IMFStreamDescriptor *sd;
1462 MF_OBJECT_TYPE obj_type;
1463 IMFMediaSource *source;
1464 IMFTopoLoader *loader;
1465 IMFByteStream *stream;
1466 IMFAttributes *attr;
1467 IMFMediaSink *sink;
1468 WCHAR *filename;
1469 BOOL selected;
1470 HRESULT hr;
1471 GUID guid;
1473 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1474 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1476 hr = MFCreateTopoLoader(NULL);
1477 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1479 hr = MFCreateTopoLoader(&loader);
1480 ok(hr == S_OK, "Failed to create topology loader, hr %#x.\n", hr);
1482 hr = MFCreateTopology(&topology);
1483 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
1485 /* Empty topology */
1486 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1487 todo_wine
1488 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1490 hr = MFCreateSourceResolver(&resolver);
1491 ok(hr == S_OK, "Failed to create source resolver, hr %#x.\n", hr);
1493 filename = load_resource(L"test.wav");
1495 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
1496 ok(hr == S_OK, "Failed to create file stream, hr %#x.\n", hr);
1498 IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attr);
1499 IMFAttributes_SetString(attr, &MF_BYTESTREAM_CONTENT_TYPE, L"audio/wav");
1500 IMFAttributes_Release(attr);
1502 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
1503 &obj_type, (IUnknown **)&source);
1504 ok(hr == S_OK || broken(FAILED(hr)) /* Vista */, "Failed to create source, hr %#x.\n", hr);
1505 if (FAILED(hr))
1506 return;
1508 hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
1509 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
1510 if (FAILED(hr))
1511 return;
1513 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
1514 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
1516 /* Add source node. */
1517 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
1518 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
1520 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
1521 ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
1523 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
1524 ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
1526 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
1527 ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
1529 hr = IMFTopology_AddNode(topology, src_node);
1530 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
1532 /* Source node only. */
1533 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1534 todo_wine
1535 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1537 /* Add grabber sink. */
1538 hr = MFCreateMediaType(&media_type);
1539 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1541 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1542 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1543 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
1544 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1546 hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate);
1547 ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
1549 IMFMediaType_Release(media_type);
1551 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
1552 ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr);
1554 hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate);
1555 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1556 hr = IMFTopology_AddNode(topology, sink_node);
1557 ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
1559 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1560 todo_wine
1561 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1563 hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
1564 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
1566 /* Sink was not resolved. */
1567 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1568 ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1570 hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
1571 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
1573 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
1574 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1576 hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink);
1577 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1579 IMFStreamSink_Release(stream_sink);
1581 hr = IMFTopology_GetCount(topology, &count);
1582 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1583 ok(count == 0, "Unexpected count %u.\n", count);
1585 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1586 ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
1587 ok(full_topology != topology, "Unexpected instance.\n");
1589 hr = IMFTopology_GetCount(topology, &count);
1590 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1591 ok(count == 0, "Unexpected count %u.\n", count);
1593 hr = IMFTopology_GetCount(full_topology, &count);
1594 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1595 todo_wine
1596 ok(count == 1, "Unexpected count %u.\n", count);
1598 hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL);
1599 todo_wine {
1600 ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr);
1601 ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid));
1603 value = 0xdeadbeef;
1604 hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
1605 todo_wine {
1606 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1607 ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
1609 hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
1610 ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
1611 ok(full_topology != topology2, "Unexpected instance.\n");
1613 IMFTopology_Release(topology2);
1614 IMFTopology_Release(full_topology);
1616 IMFMediaSource_Release(source);
1617 IMFSourceResolver_Release(resolver);
1618 IMFByteStream_Release(stream);
1619 IMFTopoLoader_Release(loader);
1621 hr = MFShutdown();
1622 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1625 static HRESULT WINAPI testshutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **obj)
1627 if (IsEqualIID(riid, &IID_IMFShutdown) ||
1628 IsEqualIID(riid, &IID_IUnknown))
1630 *obj = iface;
1631 IMFShutdown_AddRef(iface);
1632 return S_OK;
1635 *obj = NULL;
1636 return E_NOINTERFACE;
1639 static ULONG WINAPI testshutdown_AddRef(IMFShutdown *iface)
1641 return 2;
1644 static ULONG WINAPI testshutdown_Release(IMFShutdown *iface)
1646 return 1;
1649 static HRESULT WINAPI testshutdown_Shutdown(IMFShutdown *iface)
1651 return 0xdead;
1654 static HRESULT WINAPI testshutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status)
1656 ok(0, "Unexpected call.\n");
1657 return E_NOTIMPL;
1660 static const IMFShutdownVtbl testshutdownvtbl =
1662 testshutdown_QueryInterface,
1663 testshutdown_AddRef,
1664 testshutdown_Release,
1665 testshutdown_Shutdown,
1666 testshutdown_GetShutdownStatus,
1669 static void test_MFShutdownObject(void)
1671 IMFShutdown testshutdown = { &testshutdownvtbl };
1672 IUnknown testshutdown2 = { &testservicevtbl };
1673 HRESULT hr;
1675 hr = MFShutdownObject(NULL);
1676 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1678 hr = MFShutdownObject((IUnknown *)&testshutdown);
1679 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1681 hr = MFShutdownObject(&testshutdown2);
1682 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1685 enum clock_action
1687 CLOCK_START,
1688 CLOCK_STOP,
1689 CLOCK_PAUSE,
1692 static HRESULT WINAPI test_clock_sink_QueryInterface(IMFClockStateSink *iface, REFIID riid, void **obj)
1694 if (IsEqualIID(riid, &IID_IMFClockStateSink) ||
1695 IsEqualIID(riid, &IID_IUnknown))
1697 *obj = iface;
1698 IMFClockStateSink_AddRef(iface);
1699 return S_OK;
1702 *obj = NULL;
1703 return E_NOINTERFACE;
1706 static ULONG WINAPI test_clock_sink_AddRef(IMFClockStateSink *iface)
1708 return 2;
1711 static ULONG WINAPI test_clock_sink_Release(IMFClockStateSink *iface)
1713 return 1;
1716 static HRESULT WINAPI test_clock_sink_OnClockStart(IMFClockStateSink *iface, MFTIME system_time, LONGLONG offset)
1718 return E_NOTIMPL;
1721 static HRESULT WINAPI test_clock_sink_OnClockStop(IMFClockStateSink *iface, MFTIME system_time)
1723 return E_NOTIMPL;
1726 static HRESULT WINAPI test_clock_sink_OnClockPause(IMFClockStateSink *iface, MFTIME system_time)
1728 return E_NOTIMPL;
1731 static HRESULT WINAPI test_clock_sink_OnClockRestart(IMFClockStateSink *iface, MFTIME system_time)
1733 return E_NOTIMPL;
1736 static HRESULT WINAPI test_clock_sink_OnClockSetRate(IMFClockStateSink *iface, MFTIME system_time, float rate)
1738 return E_NOTIMPL;
1741 static const IMFClockStateSinkVtbl test_clock_sink_vtbl =
1743 test_clock_sink_QueryInterface,
1744 test_clock_sink_AddRef,
1745 test_clock_sink_Release,
1746 test_clock_sink_OnClockStart,
1747 test_clock_sink_OnClockStop,
1748 test_clock_sink_OnClockPause,
1749 test_clock_sink_OnClockRestart,
1750 test_clock_sink_OnClockSetRate,
1753 static void test_presentation_clock(void)
1755 static const struct clock_state_test
1757 enum clock_action action;
1758 MFCLOCK_STATE clock_state;
1759 MFCLOCK_STATE source_state;
1760 HRESULT hr;
1762 clock_state_change[] =
1764 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID },
1765 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_INVALIDREQUEST },
1766 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_CLOCK_STATE_ALREADY_SET },
1767 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1768 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1769 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
1770 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED, MF_E_CLOCK_STATE_ALREADY_SET },
1771 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
1772 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1773 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
1774 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_CLOCK_STATE_ALREADY_SET },
1775 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_INVALIDREQUEST },
1776 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1777 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
1778 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1780 IMFClockStateSink test_sink = { &test_clock_sink_vtbl };
1781 IMFPresentationTimeSource *time_source;
1782 MFCLOCK_PROPERTIES props, props2;
1783 IMFRateControl *rate_control;
1784 IMFPresentationClock *clock;
1785 MFSHUTDOWN_STATUS status;
1786 IMFShutdown *shutdown;
1787 MFTIME systime, time;
1788 LONGLONG clock_time;
1789 MFCLOCK_STATE state;
1790 unsigned int i;
1791 DWORD value;
1792 float rate;
1793 HRESULT hr;
1794 BOOL thin;
1796 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1797 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1799 hr = MFCreatePresentationClock(&clock);
1800 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
1802 check_interface(clock, &IID_IMFTimer, TRUE);
1803 check_interface(clock, &IID_IMFRateControl, TRUE);
1804 check_interface(clock, &IID_IMFPresentationClock, TRUE);
1805 check_interface(clock, &IID_IMFShutdown, TRUE);
1806 check_interface(clock, &IID_IMFClock, TRUE);
1808 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control);
1809 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
1811 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
1812 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1814 hr = IMFPresentationClock_GetTimeSource(clock, NULL);
1815 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1817 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
1818 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1820 hr = IMFPresentationClock_GetClockCharacteristics(clock, NULL);
1821 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1823 hr = IMFPresentationClock_GetTime(clock, &time);
1824 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1826 hr = IMFPresentationClock_GetTime(clock, NULL);
1827 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1829 value = 1;
1830 hr = IMFPresentationClock_GetContinuityKey(clock, &value);
1831 ok(hr == S_OK, "Failed to get continuity key, hr %#x.\n", hr);
1832 ok(value == 0, "Unexpected value %u.\n", value);
1834 hr = IMFPresentationClock_GetProperties(clock, &props);
1835 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1837 hr = IMFPresentationClock_GetState(clock, 0, &state);
1838 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
1839 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
1841 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &clock_time, &systime);
1842 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1844 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, NULL, &systime);
1845 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1847 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, NULL);
1848 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1850 /* Sinks. */
1851 hr = IMFPresentationClock_AddClockStateSink(clock, NULL);
1852 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1854 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
1855 ok(hr == S_OK, "Failed to add a sink, hr %#x.\n", hr);
1857 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
1858 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1860 hr = IMFPresentationClock_RemoveClockStateSink(clock, NULL);
1861 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1863 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
1864 ok(hr == S_OK, "Failed to remove sink, hr %#x.\n", hr);
1866 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
1867 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1869 /* State change commands, time source is not set yet. */
1870 hr = IMFPresentationClock_Start(clock, 0);
1871 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1873 hr = IMFPresentationClock_Pause(clock);
1874 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1876 hr = IMFPresentationClock_Stop(clock);
1877 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1879 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1880 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1882 /* Set default time source. */
1883 hr = MFCreateSystemTimeSource(&time_source);
1884 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
1886 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
1887 ok(hr == S_OK, "Failed to get time source flags, hr %#x.\n", hr);
1888 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
1889 "Unexpected clock flags %#x.\n", value);
1891 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
1892 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
1894 hr = IMFPresentationTimeSource_GetProperties(time_source, &props2);
1895 ok(hr == S_OK, "Failed to get time source properties, hr %#x.\n", hr);
1897 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
1898 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
1899 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
1900 "Unexpected clock flags %#x.\n", value);
1902 hr = IMFPresentationClock_GetProperties(clock, &props);
1903 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
1904 ok(!memcmp(&props, &props2, sizeof(props)), "Unexpected clock properties.\n");
1906 /* State changes. */
1907 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
1909 switch (clock_state_change[i].action)
1911 case CLOCK_STOP:
1912 hr = IMFPresentationClock_Stop(clock);
1913 break;
1914 case CLOCK_PAUSE:
1915 hr = IMFPresentationClock_Pause(clock);
1916 break;
1917 case CLOCK_START:
1918 hr = IMFPresentationClock_Start(clock, 0);
1919 break;
1920 default:
1923 ok(hr == clock_state_change[i].hr, "%u: unexpected hr %#x.\n", i, hr);
1925 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
1926 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
1927 ok(state == clock_state_change[i].source_state, "%u: unexpected state %d.\n", i, state);
1929 hr = IMFPresentationClock_GetState(clock, 0, &state);
1930 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
1931 ok(state == clock_state_change[i].clock_state, "%u: unexpected state %d.\n", i, state);
1934 /* Clock time stamps. */
1935 hr = IMFPresentationClock_Start(clock, 10);
1936 ok(hr == S_OK, "Failed to start presentation clock, hr %#x.\n", hr);
1938 hr = IMFPresentationClock_Pause(clock);
1939 ok(hr == S_OK, "Failed to pause presentation clock, hr %#x.\n", hr);
1941 hr = IMFPresentationClock_GetTime(clock, &time);
1942 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
1944 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &clock_time, &systime);
1945 ok(hr == S_OK, "Failed to get time source time, hr %#x.\n", hr);
1946 ok(time == clock_time, "Unexpected clock time.\n");
1948 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, &systime);
1949 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
1950 ok(time == clock_time, "Unexpected clock time.\n");
1952 IMFPresentationTimeSource_Release(time_source);
1954 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
1955 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1957 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
1958 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1960 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1961 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1962 ok(rate == 1.0f, "Unexpected rate.\n");
1963 ok(!thin, "Unexpected thinning.\n");
1965 hr = IMFPresentationClock_GetState(clock, 0, &state);
1966 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
1967 ok(state == MFCLOCK_STATE_PAUSED, "Unexpected state %d.\n", state);
1969 hr = IMFPresentationClock_Start(clock, 0);
1970 ok(hr == S_OK, "Failed to stop, hr %#x.\n", hr);
1972 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1973 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1974 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1975 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1976 ok(rate == 0.0f, "Unexpected rate.\n");
1977 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.0f);
1978 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1979 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1980 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1981 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.5f);
1982 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1983 hr = IMFRateControl_SetRate(rate_control, TRUE, -1.0f);
1984 ok(hr == MF_E_THINNING_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1986 hr = IMFPresentationClock_GetState(clock, 0, &state);
1987 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
1988 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
1990 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1991 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1992 ok(rate == 0.5f, "Unexpected rate.\n");
1993 ok(!thin, "Unexpected thinning.\n");
1995 IMFRateControl_Release(rate_control);
1997 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
1998 ok(hr == S_OK, "Failed to get shutdown interface, hr %#x.\n", hr);
2000 /* Shutdown behavior. */
2001 hr = IMFShutdown_GetShutdownStatus(shutdown, NULL);
2002 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2004 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2005 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
2007 hr = IMFShutdown_Shutdown(shutdown);
2008 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2010 time_source = NULL;
2011 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
2012 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2013 ok(!!time_source, "Unexpected instance %p.\n", time_source);
2014 IMFPresentationTimeSource_Release(time_source);
2016 hr = IMFPresentationClock_GetTime(clock, &time);
2017 ok(hr == S_OK, "Failed to get time, hr %#x.\n", hr);
2019 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2020 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
2021 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
2023 hr = IMFPresentationClock_Start(clock, 0);
2024 ok(hr == S_OK, "Failed to start the clock, hr %#x.\n", hr);
2026 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2027 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
2028 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
2030 hr = IMFShutdown_Shutdown(shutdown);
2031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2033 IMFShutdown_Release(shutdown);
2035 IMFPresentationClock_Release(clock);
2037 hr = MFShutdown();
2038 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2041 static HRESULT WINAPI grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, void **obj)
2043 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
2044 IsEqualIID(riid, &IID_IMFClockStateSink) ||
2045 IsEqualIID(riid, &IID_IUnknown))
2047 *obj = iface;
2048 IMFSampleGrabberSinkCallback_AddRef(iface);
2049 return S_OK;
2052 *obj = NULL;
2053 return E_NOINTERFACE;
2056 static ULONG WINAPI grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
2058 return 2;
2061 static ULONG WINAPI grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
2063 return 1;
2066 static HRESULT WINAPI grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset)
2068 return E_NOTIMPL;
2071 static HRESULT WINAPI grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2073 return E_NOTIMPL;
2076 static HRESULT WINAPI grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2078 return E_NOTIMPL;
2081 static HRESULT WINAPI grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2083 return E_NOTIMPL;
2086 static HRESULT WINAPI grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME time, float rate)
2088 return E_NOTIMPL;
2091 static HRESULT WINAPI grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
2092 IMFPresentationClock *clock)
2094 return S_OK;
2097 static HRESULT WINAPI grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
2098 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
2100 return E_NOTIMPL;
2103 static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
2105 return S_OK;
2108 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
2110 grabber_callback_QueryInterface,
2111 grabber_callback_AddRef,
2112 grabber_callback_Release,
2113 grabber_callback_OnClockStart,
2114 grabber_callback_OnClockStop,
2115 grabber_callback_OnClockPause,
2116 grabber_callback_OnClockRestart,
2117 grabber_callback_OnClockSetRate,
2118 grabber_callback_OnSetPresentationClock,
2119 grabber_callback_OnProcessSample,
2120 grabber_callback_OnShutdown,
2123 static IMFSampleGrabberSinkCallback grabber_callback = { &grabber_callback_vtbl };
2125 static void test_sample_grabber(void)
2127 IMFMediaType *media_type, *media_type2, *media_type3;
2128 IMFMediaTypeHandler *handler, *handler2;
2129 IMFPresentationTimeSource *time_source;
2130 IMFPresentationClock *clock, *clock2;
2131 IMFStreamSink *stream, *stream2;
2132 IMFRateSupport *rate_support;
2133 IMFMediaEventGenerator *eg;
2134 IMFMediaSink *sink, *sink2;
2135 DWORD flags, count, id;
2136 IMFActivate *activate;
2137 IMFMediaEvent *event;
2138 ULONG refcount;
2139 IUnknown *unk;
2140 float rate;
2141 HRESULT hr;
2142 GUID guid;
2144 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2145 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2147 hr = MFCreateMediaType(&media_type);
2148 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2150 hr = MFCreateSampleGrabberSinkActivate(NULL, NULL, &activate);
2151 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2153 hr = MFCreateSampleGrabberSinkActivate(NULL, &grabber_callback, &activate);
2154 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2156 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2157 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2158 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2159 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2161 EXPECT_REF(media_type, 1);
2162 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2163 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2164 EXPECT_REF(media_type, 2);
2166 hr = IMFActivate_GetCount(activate, &count);
2167 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
2168 ok(!count, "Unexpected count %u.\n", count);
2170 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2171 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2173 check_interface(sink, &IID_IMFClockStateSink, TRUE);
2174 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
2175 check_interface(sink, &IID_IMFGetService, TRUE);
2176 check_interface(sink, &IID_IMFRateSupport, TRUE);
2177 check_service_interface(sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
2179 if (SUCCEEDED(MFGetService((IUnknown *)sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support)))
2181 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
2182 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2183 ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
2185 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
2186 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2187 ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
2189 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
2190 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2191 ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
2193 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
2194 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2195 ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
2197 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
2198 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2199 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2201 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
2202 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2203 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2205 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
2206 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2207 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2209 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
2210 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2211 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2213 hr = IMFRateSupport_IsRateSupported(rate_support, TRUE, 1.0f, &rate);
2214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2215 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
2217 IMFRateSupport_Release(rate_support);
2220 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2221 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2222 ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags);
2224 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2225 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
2226 ok(count == 1, "Unexpected stream count %u.\n", count);
2228 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream);
2229 ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
2231 check_interface(stream, &IID_IMFMediaEventGenerator, TRUE);
2232 check_interface(stream, &IID_IMFMediaTypeHandler, TRUE);
2234 hr = IMFStreamSink_GetIdentifier(stream, &id);
2235 ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr);
2236 ok(id == 0, "Unexpected id %#x.\n", id);
2238 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
2239 ok(hr == S_OK, "Failed to get media sink, hr %x.\n", hr);
2240 ok(sink2 == sink, "Unexpected sink.\n");
2241 IMFMediaSink_Release(sink2);
2243 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 1, &stream2);
2244 ok(hr == MF_E_INVALIDINDEX, "Unexpected hr %#x.\n", hr);
2246 hr = IMFMediaSink_GetStreamSinkById(sink, 1, &stream2);
2247 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2249 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
2250 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2252 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
2253 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2255 hr = IMFMediaSink_RemoveStreamSink(sink, 1);
2256 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2258 check_interface(sink, &IID_IMFClockStateSink, TRUE);
2260 /* Event generator. */
2261 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaEventGenerator, (void **)&eg);
2262 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
2264 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2265 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2267 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&unk);
2268 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2270 hr = IMFStreamSink_QueryInterface(stream, &IID_IMFMediaTypeHandler, (void **)&handler2);
2271 ok(hr == S_OK, "Failed to get handler interface, hr %#x.\n", hr);
2273 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2274 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2275 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2276 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2277 ok(count == 0, "Unexpected count %u.\n", count);
2278 ok(handler == handler2, "Unexpected handler.\n");
2280 IMFMediaTypeHandler_Release(handler);
2281 IMFMediaTypeHandler_Release(handler2);
2283 /* Set clock. */
2284 hr = MFCreatePresentationClock(&clock);
2285 ok(hr == S_OK, "Failed to create clock object, hr %#x.\n", hr);
2287 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
2288 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2290 hr = IMFMediaSink_GetPresentationClock(sink, &clock2);
2291 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
2293 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
2294 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2296 hr = IMFMediaSink_SetPresentationClock(sink, clock);
2297 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2299 hr = MFCreateSystemTimeSource(&time_source);
2300 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2302 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
2303 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
2304 IMFPresentationTimeSource_Release(time_source);
2306 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2307 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2309 hr = IMFActivate_ShutdownObject(activate);
2310 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2312 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2313 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2315 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2316 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2318 /* On Win8+ this initialization happens automatically. */
2319 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
2320 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
2322 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
2323 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2325 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2326 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2327 ok(count == 0, "Unexpected count %u.\n", count);
2329 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2330 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2331 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
2333 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
2334 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2335 ok(media_type2 == media_type, "Unexpected media type.\n");
2336 IMFMediaType_Release(media_type2);
2338 hr = MFCreateMediaType(&media_type2);
2339 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2341 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2342 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2344 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2345 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2347 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2348 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2350 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_Float);
2351 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2353 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2354 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2356 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2357 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2359 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
2360 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2362 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2363 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2364 IMFMediaType_Release(media_type);
2366 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
2367 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2369 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
2370 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2371 ok(media_type2 == media_type, "Unexpected media type.\n");
2372 IMFMediaType_Release(media_type);
2374 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
2375 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2377 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, NULL);
2378 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2380 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
2381 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2383 hr = MFCreateMediaType(&media_type);
2384 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2386 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2387 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2389 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
2390 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2392 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2393 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2395 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2396 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2398 media_type3 = (void *)0xdeadbeef;
2399 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2400 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2401 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2403 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1);
2404 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2406 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 1024);
2407 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2409 media_type3 = (void *)0xdeadbeef;
2410 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2411 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2412 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2414 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2415 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2417 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2418 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2420 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
2421 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2423 EXPECT_REF(clock, 3);
2424 hr = IMFMediaSink_Shutdown(sink);
2425 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2426 EXPECT_REF(clock, 1);
2428 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2429 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2431 hr = IMFMediaSink_Shutdown(sink);
2432 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2434 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2435 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2437 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
2438 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2440 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2441 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2443 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream2);
2444 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2446 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
2447 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2449 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
2450 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2452 id = 1;
2453 hr = IMFStreamSink_GetIdentifier(stream, &id);
2454 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2455 ok(id == 1, "Unexpected id %u.\n", id);
2457 media_type3 = (void *)0xdeadbeef;
2458 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2459 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2460 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2462 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2463 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2465 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
2466 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2468 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2469 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
2471 IMFMediaType_Release(media_type2);
2472 IMFMediaType_Release(media_type);
2474 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
2475 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2477 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
2478 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2480 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
2481 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2483 hr = IMFMediaTypeHandler_GetMajorType(handler, NULL);
2484 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2486 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2487 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2489 IMFMediaTypeHandler_Release(handler);
2491 handler = (void *)0xdeadbeef;
2492 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2493 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2494 ok(handler == (void *)0xdeadbeef, "Unexpected pointer.\n");
2496 hr = IMFStreamSink_GetMediaTypeHandler(stream, NULL);
2497 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2499 IMFMediaEventGenerator_Release(eg);
2500 IMFMediaSink_Release(sink);
2501 IMFStreamSink_Release(stream);
2503 refcount = IMFActivate_Release(activate);
2504 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2506 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
2507 hr = MFCreateMediaType(&media_type);
2508 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2510 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2511 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2512 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2513 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2515 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2516 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2518 hr = IMFActivate_SetUINT32(activate, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 1);
2519 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2521 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2522 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2524 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2525 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2526 ok(flags & MEDIASINK_RATELESS, "Unexpected flags %#x.\n", flags);
2528 hr = IMFActivate_ShutdownObject(activate);
2529 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2531 hr = IMFMediaSink_Shutdown(sink);
2532 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2534 IMFMediaSink_Release(sink);
2536 /* Detaching */
2537 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2538 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2540 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2541 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2542 IMFMediaSink_Release(sink);
2544 hr = IMFActivate_ShutdownObject(activate);
2545 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2547 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2548 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2550 hr = IMFActivate_GetCount(activate, &count);
2551 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2553 hr = IMFActivate_DetachObject(activate);
2554 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2556 IMFActivate_Release(activate);
2558 IMFMediaType_Release(media_type);
2559 IMFPresentationClock_Release(clock);
2561 hr = MFShutdown();
2562 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2565 static BOOL is_supported_video_type(const GUID *guid)
2567 return IsEqualGUID(guid, &MFVideoFormat_L8)
2568 || IsEqualGUID(guid, &MFVideoFormat_L16)
2569 || IsEqualGUID(guid, &MFVideoFormat_D16)
2570 || IsEqualGUID(guid, &MFVideoFormat_IYUV)
2571 || IsEqualGUID(guid, &MFVideoFormat_YV12)
2572 || IsEqualGUID(guid, &MFVideoFormat_NV12)
2573 || IsEqualGUID(guid, &MFVideoFormat_420O)
2574 || IsEqualGUID(guid, &MFVideoFormat_P010)
2575 || IsEqualGUID(guid, &MFVideoFormat_P016)
2576 || IsEqualGUID(guid, &MFVideoFormat_UYVY)
2577 || IsEqualGUID(guid, &MFVideoFormat_YUY2)
2578 || IsEqualGUID(guid, &MFVideoFormat_P208)
2579 || IsEqualGUID(guid, &MFVideoFormat_NV11)
2580 || IsEqualGUID(guid, &MFVideoFormat_AYUV)
2581 || IsEqualGUID(guid, &MFVideoFormat_ARGB32)
2582 || IsEqualGUID(guid, &MFVideoFormat_RGB32)
2583 || IsEqualGUID(guid, &MFVideoFormat_A2R10G10B10)
2584 || IsEqualGUID(guid, &MFVideoFormat_A16B16G16R16F)
2585 || IsEqualGUID(guid, &MFVideoFormat_RGB24)
2586 || IsEqualGUID(guid, &MFVideoFormat_I420)
2587 || IsEqualGUID(guid, &MFVideoFormat_YVYU)
2588 || IsEqualGUID(guid, &MFVideoFormat_RGB555)
2589 || IsEqualGUID(guid, &MFVideoFormat_RGB565)
2590 || IsEqualGUID(guid, &MFVideoFormat_RGB8)
2591 || IsEqualGUID(guid, &MFVideoFormat_Y216)
2592 || IsEqualGUID(guid, &MFVideoFormat_v410)
2593 || IsEqualGUID(guid, &MFVideoFormat_Y41P)
2594 || IsEqualGUID(guid, &MFVideoFormat_Y41T)
2595 || IsEqualGUID(guid, &MFVideoFormat_Y42T)
2596 || IsEqualGUID(guid, &MFVideoFormat_ABGR32);
2599 static void test_video_processor(void)
2601 DWORD input_count, output_count, input_id, output_id, flags;
2602 DWORD input_min, input_max, output_min, output_max, i, count;
2603 IMFAttributes *attributes, *attributes2;
2604 IMFMediaType *media_type, *media_type2;
2605 MFT_OUTPUT_DATA_BUFFER output_buffer;
2606 MFT_OUTPUT_STREAM_INFO output_info;
2607 MFT_INPUT_STREAM_INFO input_info;
2608 IMFSample *sample, *sample2;
2609 IMFTransform *transform;
2610 IMFMediaBuffer *buffer;
2611 IMFMediaEvent *event;
2612 IUnknown *unk;
2613 HRESULT hr;
2614 GUID guid;
2616 hr = CoInitialize(NULL);
2617 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2619 hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
2620 (void **)&transform);
2621 if (FAILED(hr))
2623 skip("Failed to create Video Processor instance, skipping tests.\n");
2624 goto failed;
2627 hr = IMFTransform_QueryInterface(transform, &IID_IMFMediaEventGenerator, (void **)&unk);
2628 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2630 hr = IMFTransform_QueryInterface(transform, &IID_IMFShutdown, (void **)&unk);
2631 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2633 /* Transform global attributes. */
2634 hr = IMFTransform_GetAttributes(transform, &attributes);
2635 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
2636 hr = IMFTransform_GetAttributes(transform, &attributes2);
2637 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
2638 ok(attributes == attributes2, "Unexpected instance.\n");
2639 IMFAttributes_Release(attributes);
2640 IMFAttributes_Release(attributes2);
2642 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
2643 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
2644 ok(input_min == input_max && input_min == 1 && output_min == output_max && output_min == 1,
2645 "Unexpected stream limits.\n");
2647 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
2648 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
2649 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u, %u.\n", input_count, output_count);
2651 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
2652 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2654 input_id = 100;
2655 hr = IMFTransform_AddInputStreams(transform, 1, &input_id);
2656 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2658 hr = IMFTransform_DeleteInputStream(transform, 0);
2659 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2661 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
2662 todo_wine
2663 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2665 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
2666 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2668 hr = IMFTransform_GetOutputStatus(transform, &flags);
2669 todo_wine
2670 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2672 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
2673 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
2674 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes2);
2675 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
2676 ok(attributes == attributes2, "Unexpected instance.\n");
2677 IMFAttributes_Release(attributes);
2678 IMFAttributes_Release(attributes2);
2680 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
2681 todo_wine
2682 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2684 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
2685 todo_wine
2686 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2688 hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type);
2689 todo_wine
2690 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2692 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
2693 todo_wine
2694 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2696 hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type);
2697 todo_wine
2698 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2700 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
2701 todo_wine
2702 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2704 memset(&input_info, 0xcc, sizeof(input_info));
2705 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
2706 todo_wine {
2707 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2708 ok(input_info.dwFlags == 0, "Unexpected flag %#x.\n", input_info.dwFlags);
2709 ok(input_info.cbSize == 0, "Unexpected size %u.\n", input_info.cbSize);
2710 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
2711 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
2713 hr = MFCreateMediaEvent(MEUnknown, &GUID_NULL, S_OK, NULL, &event);
2714 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2715 hr = IMFTransform_ProcessEvent(transform, 0, event);
2716 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2717 hr = IMFTransform_ProcessEvent(transform, 1, event);
2718 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2719 IMFMediaEvent_Release(event);
2721 /* Configure stream types. */
2722 for (i = 0;;++i)
2724 if (FAILED(hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type)))
2726 todo_wine
2727 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2728 break;
2731 hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type2);
2732 ok(hr == S_OK, "Failed to get available type, hr %#x.\n", hr);
2733 ok(media_type != media_type2, "Unexpected instance.\n");
2734 IMFMediaType_Release(media_type2);
2736 hr = IMFMediaType_GetMajorType(media_type, &guid);
2737 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2738 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
2740 hr = IMFMediaType_GetCount(media_type, &count);
2741 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
2742 ok(count == 2, "Unexpected count %u.\n", count);
2744 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
2745 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
2746 ok(is_supported_video_type(&guid), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid));
2748 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
2749 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2751 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2752 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2754 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
2755 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2757 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
2758 if (IsEqualGUID(&guid, &MFVideoFormat_L8) || IsEqualGUID(&guid, &MFVideoFormat_L16)
2759 || IsEqualGUID(&guid, &MFVideoFormat_D16) || IsEqualGUID(&guid, &MFVideoFormat_420O)
2760 || IsEqualGUID(&guid, &MFVideoFormat_A16B16G16R16F))
2762 IMFMediaType_Release(media_type);
2763 continue;
2766 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
2767 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2769 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
2770 ok(hr == S_OK, "Failed to test input type %s, hr %#x.\n", wine_dbgstr_guid(&guid), hr);
2772 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2773 ok(hr == S_OK, "Failed to test input type, hr %#x.\n", hr);
2775 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
2776 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2777 ok(media_type != media_type2, "Unexpected instance.\n");
2778 IMFMediaType_Release(media_type2);
2780 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
2781 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
2782 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected input status %#x.\n", flags);
2784 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
2785 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2786 ok(input_info.dwFlags == 0, "Unexpected flags %#x.\n", input_info.dwFlags);
2787 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
2788 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
2790 IMFMediaType_Release(media_type);
2793 /* IYUV -> RGB32 */
2794 hr = MFCreateMediaType(&media_type);
2795 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2797 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
2798 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2800 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_IYUV);
2801 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2803 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
2804 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2806 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2807 todo_wine
2808 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
2810 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
2811 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2813 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
2814 todo_wine
2815 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
2817 memset(&output_info, 0, sizeof(output_info));
2818 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
2819 todo_wine
2820 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2821 ok(output_info.dwFlags == 0, "Unexpected flags %#x.\n", output_info.dwFlags);
2822 todo_wine
2823 ok(output_info.cbSize > 0, "Unexpected size %u.\n", output_info.cbSize);
2824 ok(output_info.cbAlignment == 0, "Unexpected alignment %u.\n", output_info.cbAlignment);
2826 hr = MFCreateSample(&sample);
2827 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2829 hr = MFCreateSample(&sample2);
2830 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2832 memset(&output_buffer, 0, sizeof(output_buffer));
2833 output_buffer.pSample = sample;
2834 flags = 0;
2835 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2836 todo_wine
2837 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2838 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2839 ok(flags == 0, "Unexpected status %#x.\n", flags);
2841 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
2842 todo_wine
2843 ok(hr == S_OK, "Failed to push a sample, hr %#x.\n", hr);
2845 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
2846 todo_wine
2847 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
2849 memset(&output_buffer, 0, sizeof(output_buffer));
2850 output_buffer.pSample = sample;
2851 flags = 0;
2852 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2853 todo_wine
2854 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2855 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2856 ok(flags == 0, "Unexpected status %#x.\n", flags);
2858 hr = IMFSample_SetSampleTime(sample2, 0);
2859 ok(hr == S_OK, "Failed to set sample time, hr %#x.\n", hr);
2860 memset(&output_buffer, 0, sizeof(output_buffer));
2861 output_buffer.pSample = sample;
2862 flags = 0;
2863 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2864 todo_wine
2865 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2866 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2867 ok(flags == 0, "Unexpected status %#x.\n", flags);
2869 hr = MFCreateMemoryBuffer(1024 * 1024, &buffer);
2870 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2872 hr = IMFSample_AddBuffer(sample2, buffer);
2873 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
2875 hr = IMFSample_AddBuffer(sample, buffer);
2876 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
2878 memset(&output_buffer, 0, sizeof(output_buffer));
2879 output_buffer.pSample = sample;
2880 flags = 0;
2881 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2882 todo_wine
2883 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr);
2884 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2885 ok(flags == 0, "Unexpected status %#x.\n", flags);
2887 if (SUCCEEDED(hr))
2889 memset(&output_buffer, 0, sizeof(output_buffer));
2890 output_buffer.pSample = sample;
2891 flags = 0;
2892 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2893 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2894 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2895 ok(flags == 0, "Unexpected status %#x.\n", flags);
2898 IMFSample_Release(sample2);
2899 IMFSample_Release(sample);
2900 IMFMediaBuffer_Release(buffer);
2902 IMFMediaType_Release(media_type);
2904 IMFTransform_Release(transform);
2906 failed:
2907 CoUninitialize();
2910 static void test_quality_manager(void)
2912 IMFQualityManager *manager;
2913 HRESULT hr;
2915 hr = MFCreateStandardQualityManager(&manager);
2916 ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr);
2918 hr = IMFQualityManager_NotifyPresentationClock(manager, NULL);
2919 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2921 IMFQualityManager_Release(manager);
2924 static void test_sar(void)
2926 IMFPresentationClock *present_clock, *present_clock2;
2927 IMFMediaType *mediatype, *mediatype2, *mediatype3;
2928 IMFMediaTypeHandler *handler, *handler2;
2929 IMFPresentationTimeSource *time_source;
2930 IMFSimpleAudioVolume *simple_volume;
2931 IMFAudioStreamVolume *stream_volume;
2932 IMFClockStateSink *state_sink;
2933 IMFMediaSink *sink, *sink2;
2934 IMFStreamSink *stream_sink;
2935 IMFAttributes *attributes;
2936 DWORD i, id, flags, count;
2937 IMFActivate *activate;
2938 MFCLOCK_STATE state;
2939 IMFClock *clock;
2940 IUnknown *unk;
2941 HRESULT hr;
2942 GUID guid;
2943 BOOL mute;
2944 int found;
2946 hr = CoInitialize(NULL);
2947 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2949 hr = MFCreateAudioRenderer(NULL, &sink);
2950 if (hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE)
2952 skip("No audio playback device available.\n");
2953 CoUninitialize();
2954 return;
2956 ok(hr == S_OK, "Failed to create renderer, hr %#x.\n", hr);
2958 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2959 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
2961 hr = MFCreatePresentationClock(&present_clock);
2962 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
2964 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&time_source);
2965 todo_wine
2966 ok(hr == S_OK, "Failed to get time source interface, hr %#x.\n", hr);
2968 if (SUCCEEDED(hr))
2970 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
2971 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
2973 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &flags);
2974 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
2975 ok(flags == MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ, "Unexpected flags %#x.\n", flags);
2977 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2978 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2979 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
2981 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&state_sink);
2982 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
2984 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
2985 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
2987 IMFClockStateSink_Release(state_sink);
2989 IMFPresentationTimeSource_Release(time_source);
2991 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
2992 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2994 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
2995 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2997 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
2998 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3000 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
3001 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3002 ok(count == 1, "Unexpected count %u.\n", count);
3004 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3005 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3006 ok(flags == (MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL), "Unexpected flags %#x.\n", flags);
3008 check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
3009 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
3010 check_interface(sink, &IID_IMFClockStateSink, TRUE);
3012 /* Clock */
3013 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&state_sink);
3014 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3016 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3017 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3019 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3020 ok(hr == MF_E_INVALID_STATE_TRANSITION, "Unexpected hr %#x.\n", hr);
3022 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3023 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3025 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3026 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3028 IMFClockStateSink_Release(state_sink);
3030 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
3031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3033 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3034 todo_wine
3035 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
3037 hr = MFCreateSystemTimeSource(&time_source);
3038 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3040 hr = IMFPresentationClock_SetTimeSource(present_clock, time_source);
3041 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
3042 IMFPresentationTimeSource_Release(time_source);
3044 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3045 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3047 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
3048 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3050 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
3051 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3052 ok(present_clock == present_clock2, "Unexpected instance.\n");
3053 IMFPresentationClock_Release(present_clock2);
3055 /* Stream */
3056 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
3057 ok(hr == S_OK, "Failed to get a stream, hr %#x.\n", hr);
3059 check_interface(stream_sink, &IID_IMFMediaEventGenerator, TRUE);
3061 hr = IMFStreamSink_GetIdentifier(stream_sink, &id);
3062 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3063 ok(!id, "Unexpected id.\n");
3065 hr = IMFStreamSink_GetMediaSink(stream_sink, &sink2);
3066 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3067 ok(sink == sink2, "Unexpected object.\n");
3068 IMFMediaSink_Release(sink2);
3070 hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler);
3071 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3073 hr = IMFStreamSink_QueryInterface(stream_sink, &IID_IMFMediaTypeHandler, (void **)&handler2);
3074 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3075 ok(handler2 == handler, "Unexpected instance.\n");
3076 IMFMediaTypeHandler_Release(handler2);
3078 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3079 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3080 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
3082 count = 0;
3083 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
3084 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3085 ok(!!count, "Unexpected type count %u.\n", count);
3087 /* A number of same major/subtype entries are returned, with different degrees of finer format
3088 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
3090 for (i = 0, found = -1; i < count; ++i)
3092 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, i, &mediatype);
3093 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3095 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL)))
3096 found = i;
3097 IMFMediaType_Release(mediatype);
3099 if (found != -1) break;
3101 ok(found != -1, "Haven't found a supported type.\n");
3103 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &mediatype);
3104 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3106 hr = MFCreateMediaType(&mediatype);
3107 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3109 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
3110 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3111 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
3113 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3114 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3115 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3116 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3118 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3119 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3120 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3121 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3123 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype);
3124 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3126 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, found, &mediatype2);
3127 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3129 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, found, &mediatype3);
3130 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3131 ok(mediatype2 == mediatype3, "Unexpected instance.\n");
3132 IMFMediaType_Release(mediatype3);
3134 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype2, NULL);
3135 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3137 IMFMediaType_Release(mediatype);
3139 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype2);
3140 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3142 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &mediatype);
3143 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3144 ok(mediatype == mediatype2, "Unexpected instance.\n");
3145 IMFMediaType_Release(mediatype);
3147 IMFMediaType_Release(mediatype2);
3149 /* Reset back to uninitialized state. */
3150 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3151 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3153 IMFMediaTypeHandler_Release(handler);
3155 /* State change with initialized stream. */
3156 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&state_sink);
3157 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3159 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3160 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3162 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3163 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3165 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3166 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3168 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3169 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3171 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3172 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3174 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3175 ok(hr == MF_E_INVALID_STATE_TRANSITION, "Unexpected hr %#x.\n", hr);
3177 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3178 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3180 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3181 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3183 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3184 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3186 IMFClockStateSink_Release(state_sink);
3188 IMFStreamSink_Release(stream_sink);
3190 /* Volume control */
3191 hr = MFGetService((IUnknown *)sink, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, (void **)&simple_volume);
3192 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3194 hr = IMFSimpleAudioVolume_GetMute(simple_volume, &mute);
3195 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3197 IMFSimpleAudioVolume_Release(simple_volume);
3199 hr = MFGetService((IUnknown *)sink, &MR_STREAM_VOLUME_SERVICE, &IID_IMFAudioStreamVolume, (void **)&stream_volume);
3200 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3202 hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, &count);
3203 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3205 hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, NULL);
3206 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3208 IMFAudioStreamVolume_Release(stream_volume);
3210 hr = MFGetService((IUnknown *)sink, &MR_AUDIO_POLICY_SERVICE, &IID_IMFAudioPolicy, (void **)&unk);
3211 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3212 IUnknown_Release(unk);
3214 /* Shutdown */
3215 EXPECT_REF(present_clock, 2);
3216 hr = IMFMediaSink_Shutdown(sink);
3217 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3218 EXPECT_REF(present_clock, 1);
3220 hr = IMFMediaSink_Shutdown(sink);
3221 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3223 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
3224 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3226 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
3227 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3229 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
3230 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3232 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
3233 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3235 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3236 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3238 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
3239 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3241 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3242 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3244 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
3245 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3247 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
3248 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3250 IMFMediaSink_Release(sink);
3252 /* Activation */
3253 hr = MFCreateAudioRendererActivate(&activate);
3254 ok(hr == S_OK, "Failed to create activation object, hr %#x.\n", hr);
3256 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3257 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3259 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
3260 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3261 ok(sink == sink2, "Unexpected instance.\n");
3262 IMFMediaSink_Release(sink2);
3264 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3265 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
3267 hr = IMFActivate_ShutdownObject(activate);
3268 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3270 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3271 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3273 IMFMediaSink_Release(sink);
3275 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3276 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3278 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3279 todo_wine
3280 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3282 IMFMediaSink_Release(sink);
3284 hr = IMFActivate_DetachObject(activate);
3285 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3287 IMFActivate_Release(activate);
3289 IMFPresentationClock_Release(present_clock);
3291 hr = MFShutdown();
3292 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
3294 /* SAR attributes */
3295 hr = MFCreateAttributes(&attributes, 0);
3296 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
3298 /* Specify role. */
3299 hr = IMFAttributes_SetUINT32(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia);
3300 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3302 hr = MFCreateAudioRenderer(attributes, &sink);
3303 ok(hr == S_OK, "Failed to create a sink, hr %#x.\n", hr);
3304 IMFMediaSink_Release(sink);
3306 /* Invalid endpoint. */
3307 hr = IMFAttributes_SetString(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, L"endpoint");
3308 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3310 hr = MFCreateAudioRenderer(attributes, &sink);
3311 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3313 hr = IMFAttributes_DeleteItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE);
3314 ok(hr == S_OK, "Failed to remove attribute, hr %#x.\n", hr);
3316 hr = MFCreateAudioRenderer(attributes, &sink);
3317 ok(hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE, "Failed to create a sink, hr %#x.\n", hr);
3319 CoUninitialize();
3322 static void test_evr(void)
3324 IMFVideoSampleAllocatorCallback *allocator_callback;
3325 IMFStreamSink *stream_sink, *stream_sink2;
3326 IMFVideoDisplayControl *display_control;
3327 IMFMediaType *media_type, *media_type2;
3328 IMFVideoSampleAllocator *allocator;
3329 IMFMediaTypeHandler *type_handler;
3330 IMFVideoRenderer *video_renderer;
3331 IMFMediaSink *sink, *sink2;
3332 IMFAttributes *attributes;
3333 DWORD flags, count, value;
3334 IMFActivate *activate;
3335 HWND window, window2;
3336 LONG sample_count;
3337 IMFGetService *gs;
3338 IMFSample *sample;
3339 IUnknown *unk;
3340 UINT64 window3;
3341 HRESULT hr;
3342 GUID guid;
3344 hr = CoInitialize(NULL);
3345 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
3347 hr = MFCreateVideoRenderer(&IID_IMFVideoRenderer, (void **)&video_renderer);
3348 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3350 hr = IMFVideoRenderer_InitializeRenderer(video_renderer, NULL, NULL);
3351 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3353 IMFVideoRenderer_Release(video_renderer);
3355 hr = MFCreateVideoRendererActivate(NULL, NULL);
3356 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3358 /* Window */
3359 window = create_window();
3360 hr = MFCreateVideoRendererActivate(window, &activate);
3361 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
3363 hr = IMFActivate_GetUINT64(activate, &MF_ACTIVATE_VIDEO_WINDOW, &window3);
3364 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3365 ok(UlongToHandle(window3) == window, "Unexpected value.\n");
3367 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3368 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3370 check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
3371 check_interface(sink, &IID_IMFVideoRenderer, TRUE);
3372 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
3373 check_interface(sink, &IID_IMFClockStateSink, TRUE);
3374 check_interface(sink, &IID_IMFGetService, TRUE);
3375 check_interface(sink, &IID_IMFQualityAdvise, TRUE);
3377 hr = MFGetService((IUnknown *)sink, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl,
3378 (void **)&display_control);
3379 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3381 window2 = NULL;
3382 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window2);
3383 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3384 ok(window2 == window, "Unexpected window %p.\n", window2);
3386 IMFVideoDisplayControl_Release(display_control);
3387 IMFMediaSink_Release(sink);
3388 IMFActivate_Release(activate);
3389 DestroyWindow(window);
3391 hr = MFCreateVideoRendererActivate(NULL, &activate);
3392 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
3394 hr = IMFActivate_GetCount(activate, &count);
3395 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3396 ok(count == 1, "Unexpected count %u.\n", count);
3398 hr = IMFActivate_GetUINT64(activate, &MF_ACTIVATE_VIDEO_WINDOW, &window3);
3399 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3400 ok(!window3, "Unexpected value.\n");
3402 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3403 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3405 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFAttributes, (void **)&attributes);
3406 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3407 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFMediaSink, (void **)&unk);
3408 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3409 IUnknown_Release(unk);
3410 hr = IMFAttributes_GetCount(attributes, &count);
3411 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3412 ok(!!count, "Unexpected count %u.\n", count);
3413 /* Rendering preferences are not immediately propagated to the presenter. */
3414 hr = IMFAttributes_SetUINT32(attributes, &EVRConfig_ForceBob, 1);
3415 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3416 hr = MFGetService((IUnknown *)sink, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
3417 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3418 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
3419 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3420 ok(!flags, "Unexpected flags %#x.\n", flags);
3421 IMFVideoDisplayControl_Release(display_control);
3422 IMFAttributes_Release(attributes);
3424 /* Primary stream type handler. */
3425 hr = IMFMediaSink_GetStreamSinkById(sink, 0, &stream_sink);
3426 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3428 hr = IMFStreamSink_QueryInterface(stream_sink, &IID_IMFAttributes, (void **)&attributes);
3429 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3430 hr = IMFAttributes_GetCount(attributes, &count);
3431 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3432 ok(count == 2, "Unexpected count %u.\n", count);
3433 value = 0;
3434 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &value);
3435 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3436 ok(value == 1, "Unexpected attribute value %u.\n", value);
3437 value = 0;
3438 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_D3D_AWARE, &value);
3439 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3440 ok(value == 1, "Unexpected attribute value %u.\n", value);
3442 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFStreamSink, (void **)&unk);
3443 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3444 IUnknown_Release(unk);
3445 IMFAttributes_Release(attributes);
3447 hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &type_handler);
3448 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3450 hr = IMFMediaTypeHandler_GetMajorType(type_handler, NULL);
3451 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3453 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &guid);
3454 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3455 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
3457 /* Supported types are not advertised. */
3458 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, NULL);
3459 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3461 count = 1;
3462 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3463 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3464 ok(!count, "Unexpected count %u.\n", count);
3466 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, NULL);
3467 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3469 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, &media_type);
3470 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3472 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, NULL);
3473 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3475 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3476 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3478 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3479 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3481 hr = MFCreateMediaType(&media_type);
3482 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3484 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3485 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3487 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
3488 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3490 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
3491 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3493 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3494 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3496 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3497 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3499 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
3500 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3502 media_type2 = (void *)0x1;
3503 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3504 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3505 ok(!media_type2, "Unexpected media type %p.\n", media_type2);
3507 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3508 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3510 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type2);
3511 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3512 hr = IMFMediaType_QueryInterface(media_type2, &IID_IMFVideoMediaType, (void **)&unk);
3513 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3514 IUnknown_Release(unk);
3515 IMFMediaType_Release(media_type2);
3517 IMFMediaType_Release(media_type);
3519 IMFMediaTypeHandler_Release(type_handler);
3521 /* Stream uses an allocator. */
3522 hr = MFGetService((IUnknown *)stream_sink, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator,
3523 (void **)&allocator);
3524 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3526 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_callback);
3527 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3529 sample_count = 0;
3530 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback, &sample_count);
3531 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3532 ok(!sample_count, "Unexpected sample count %d.\n", sample_count);
3534 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
3535 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3537 IMFVideoSampleAllocatorCallback_Release(allocator_callback);
3538 IMFVideoSampleAllocator_Release(allocator);
3540 /* Same test for a substream. */
3541 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream_sink2);
3542 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3544 hr = MFGetService((IUnknown *)stream_sink2, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator,
3545 (void **)&allocator);
3546 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3547 IMFVideoSampleAllocator_Release(allocator);
3549 hr = IMFMediaSink_RemoveStreamSink(sink, 1);
3550 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3552 IMFStreamSink_Release(stream_sink2);
3554 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3555 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3556 ok(flags == (MEDIASINK_CAN_PREROLL | MEDIASINK_CLOCK_REQUIRED), "Unexpected flags %#x.\n", flags);
3558 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFGetService, (void **)&gs);
3559 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3561 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, (void **)&unk);
3562 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3563 IUnknown_Release(unk);
3565 IMFGetService_Release(gs);
3567 hr = IMFActivate_ShutdownObject(activate);
3568 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3570 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3571 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3573 /* Activate again. */
3574 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
3575 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3576 todo_wine
3577 ok(sink == sink2, "Unexpected instance.\n");
3578 IMFMediaSink_Release(sink2);
3580 hr = IMFActivate_DetachObject(activate);
3581 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3583 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3584 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3586 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
3587 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
3589 hr = IMFActivate_ShutdownObject(activate);
3590 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3592 IMFMediaSink_Release(sink2);
3593 IMFMediaSink_Release(sink);
3595 IMFActivate_Release(activate);
3597 CoUninitialize();
3600 static void test_MFCreateSimpleTypeHandler(void)
3602 IMFMediaType *media_type, *media_type2, *media_type3;
3603 IMFMediaTypeHandler *handler;
3604 DWORD count;
3605 HRESULT hr;
3606 GUID guid;
3608 hr = MFCreateSimpleTypeHandler(&handler);
3609 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3611 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
3612 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3614 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
3615 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
3617 count = 0;
3618 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
3619 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3620 ok(count == 1, "Unexpected count %u.\n", count);
3622 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
3623 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3625 media_type = (void *)0xdeadbeef;
3626 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
3627 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3628 ok(!media_type, "Unexpected pointer.\n");
3630 hr = MFCreateMediaType(&media_type);
3631 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3633 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
3634 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
3636 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
3637 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3639 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type2);
3640 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3641 ok(media_type2 == media_type, "Unexpected type.\n");
3642 IMFMediaType_Release(media_type2);
3644 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
3645 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3647 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
3648 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3650 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type2);
3651 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3653 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 1, &media_type2);
3654 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3656 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
3657 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3658 ok(media_type == media_type2, "Unexpected pointer.\n");
3659 IMFMediaType_Release(media_type2);
3661 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3662 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3664 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3665 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3667 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3668 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3669 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
3671 hr = MFCreateMediaType(&media_type3);
3672 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3674 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, NULL);
3675 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3677 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3678 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3680 /* Different major types. */
3681 media_type2 = (void *)0xdeadbeef;
3682 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3683 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3684 ok(!media_type2, "Unexpected pointer.\n");
3686 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3687 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3689 media_type2 = (void *)0xdeadbeef;
3690 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3691 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3692 ok(!media_type2, "Unexpected pointer.\n");
3694 /* Handler missing subtype. */
3695 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3696 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3698 media_type2 = (void *)0xdeadbeef;
3699 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3700 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3701 ok(!media_type2, "Unexpected pointer.\n");
3703 /* Different subtypes. */
3704 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
3705 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3707 media_type2 = (void *)0xdeadbeef;
3708 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3709 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3710 ok(!media_type2, "Unexpected pointer.\n");
3712 /* Same major/subtype. */
3713 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
3714 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3716 media_type2 = (void *)0xdeadbeef;
3717 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3718 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3719 ok(!media_type2, "Unexpected pointer.\n");
3721 /* Set one more attribute. */
3722 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)4 << 32 | 4);
3723 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3725 media_type2 = (void *)0xdeadbeef;
3726 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3727 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3728 ok(!media_type2, "Unexpected pointer.\n");
3730 IMFMediaType_Release(media_type3);
3731 IMFMediaType_Release(media_type);
3733 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3734 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3736 media_type = (void *)0xdeadbeef;
3737 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
3738 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3739 ok(!media_type, "Unexpected pointer.\n");
3741 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3742 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3744 IMFMediaTypeHandler_Release(handler);
3747 static void test_MFGetSupportedMimeTypes(void)
3749 PROPVARIANT value;
3750 HRESULT hr;
3752 hr = MFGetSupportedMimeTypes(NULL);
3753 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3755 value.vt = VT_EMPTY;
3756 hr = MFGetSupportedMimeTypes(&value);
3757 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3758 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
3760 PropVariantClear(&value);
3763 static void test_MFGetSupportedSchemes(void)
3765 PROPVARIANT value;
3766 HRESULT hr;
3768 hr = MFGetSupportedSchemes(NULL);
3769 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3771 value.vt = VT_EMPTY;
3772 hr = MFGetSupportedSchemes(&value);
3773 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3774 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
3776 PropVariantClear(&value);
3779 static BOOL is_sample_copier_available_type(IMFMediaType *type)
3781 GUID major = { 0 };
3782 UINT32 count;
3783 HRESULT hr;
3785 hr = IMFMediaType_GetMajorType(type, &major);
3786 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3788 hr = IMFMediaType_GetCount(type, &count);
3789 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3790 ok(count == 1, "Unexpected attribute count %u.\n", count);
3792 return IsEqualGUID(&major, &MFMediaType_Video) || IsEqualGUID(&major, &MFMediaType_Audio);
3795 static void test_sample_copier(void)
3797 IMFAttributes *attributes, *attributes2;
3798 DWORD in_min, in_max, out_min, out_max;
3799 IMFMediaType *mediatype, *mediatype2;
3800 MFT_OUTPUT_STREAM_INFO output_info;
3801 IMFSample *sample, *client_sample;
3802 MFT_INPUT_STREAM_INFO input_info;
3803 DWORD input_count, output_count;
3804 MFT_OUTPUT_DATA_BUFFER buffer;
3805 IMFMediaBuffer *media_buffer;
3806 DWORD count, flags, status;
3807 IMFTransform *copier;
3808 UINT32 value;
3809 HRESULT hr;
3811 hr = MFCreateSampleCopierMFT(&copier);
3812 ok(hr == S_OK, "Failed to create sample copier, hr %#x.\n", hr);
3814 hr = IMFTransform_GetAttributes(copier, &attributes);
3815 ok(hr == S_OK, "Failed to get transform attributes, hr %#x.\n", hr);
3816 hr = IMFTransform_GetAttributes(copier, &attributes2);
3817 ok(hr == S_OK, "Failed to get transform attributes, hr %#x.\n", hr);
3818 ok(attributes == attributes2, "Unexpected instance.\n");
3819 IMFAttributes_Release(attributes2);
3820 hr = IMFAttributes_GetCount(attributes, &count);
3821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3822 ok(count == 1, "Unexpected attribute count %u.\n", count);
3823 hr = IMFAttributes_GetUINT32(attributes, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, &value);
3824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3825 ok(!!value, "Unexpected value %u.\n", value);
3826 IMFAttributes_Release(attributes);
3828 hr = IMFTransform_GetInputStreamAttributes(copier, 0, &attributes);
3829 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3831 hr = IMFTransform_GetInputStreamAttributes(copier, 1, &attributes);
3832 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3834 hr = IMFTransform_GetOutputStreamAttributes(copier, 0, &attributes);
3835 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3837 hr = IMFTransform_GetOutputStreamAttributes(copier, 1, &attributes);
3838 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3840 hr = IMFTransform_SetOutputBounds(copier, 0, 0);
3841 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3843 /* No dynamic streams. */
3844 input_count = output_count = 0;
3845 hr = IMFTransform_GetStreamCount(copier, &input_count, &output_count);
3846 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
3847 ok(input_count == 1 && output_count == 1, "Unexpected streams count.\n");
3849 hr = IMFTransform_GetStreamLimits(copier, &in_min, &in_max, &out_min, &out_max);
3850 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
3851 ok(in_min == in_max && in_min == 1 && out_min == out_max && out_min == 1, "Unexpected stream limits.\n");
3853 hr = IMFTransform_GetStreamIDs(copier, 1, &input_count, 1, &output_count);
3854 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3856 hr = IMFTransform_DeleteInputStream(copier, 0);
3857 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3859 /* Available types. */
3860 hr = IMFTransform_GetInputAvailableType(copier, 0, 0, &mediatype);
3861 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3862 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
3863 IMFMediaType_Release(mediatype);
3865 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype);
3866 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3867 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
3868 IMFMediaType_Release(mediatype);
3870 hr = IMFTransform_GetInputAvailableType(copier, 0, 2, &mediatype);
3871 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3873 hr = IMFTransform_GetInputAvailableType(copier, 1, 0, &mediatype);
3874 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3876 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype);
3877 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3879 hr = IMFTransform_GetOutputAvailableType(copier, 1, 0, &mediatype);
3880 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3882 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype);
3883 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3885 hr = IMFTransform_GetInputCurrentType(copier, 1, &mediatype);
3886 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3888 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype);
3889 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3891 hr = IMFTransform_GetOutputCurrentType(copier, 1, &mediatype);
3892 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3894 hr = MFCreateSample(&sample);
3895 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
3897 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
3898 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3900 hr = MFCreateMediaType(&mediatype);
3901 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3903 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3904 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3906 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3907 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3909 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3910 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3912 hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16);
3913 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3915 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
3916 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3917 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
3918 ok(!output_info.cbSize, "Unexpected size %u.\n", output_info.cbSize);
3919 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
3921 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
3922 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3924 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
3925 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
3926 ok(!input_info.cbSize, "Unexpected size %u.\n", input_info.cbSize);
3927 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
3928 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
3930 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3931 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
3933 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
3934 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3935 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
3936 ok(output_info.cbSize == 16 * 16, "Unexpected size %u.\n", output_info.cbSize);
3937 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
3939 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3940 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3941 IMFMediaType_Release(mediatype2);
3943 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
3944 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3946 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
3947 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3949 /* Setting input type resets output type. */
3950 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3951 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3952 IMFMediaType_Release(mediatype2);
3954 hr = IMFTransform_SetInputType(copier, 0, mediatype, 0);
3955 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
3957 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3958 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3960 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype2);
3961 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3962 ok(is_sample_copier_available_type(mediatype2), "Unexpected type.\n");
3963 IMFMediaType_Release(mediatype2);
3965 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
3966 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3967 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
3968 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
3969 ok(input_info.cbSize == 16 * 16, "Unexpected size %u.\n", input_info.cbSize);
3970 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
3971 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
3973 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype2);
3974 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3975 hr = IMFMediaType_IsEqual(mediatype2, mediatype, &flags);
3976 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3977 IMFMediaType_Release(mediatype2);
3979 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
3980 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
3981 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected flags %#x.\n", flags);
3983 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
3984 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3985 IMFMediaType_Release(mediatype2);
3987 hr = IMFTransform_GetOutputStatus(copier, &flags);
3988 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3990 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3991 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
3993 hr = IMFTransform_GetOutputStatus(copier, &flags);
3994 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
3995 ok(!flags, "Unexpected flags %#x.\n", flags);
3997 /* Pushing samples. */
3998 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
3999 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4001 hr = IMFSample_AddBuffer(sample, media_buffer);
4002 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
4003 IMFMediaBuffer_Release(media_buffer);
4005 EXPECT_REF(sample, 1);
4006 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4007 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4008 EXPECT_REF(sample, 2);
4010 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
4011 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
4012 ok(!flags, "Unexpected flags %#x.\n", flags);
4014 hr = IMFTransform_GetOutputStatus(copier, &flags);
4015 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
4016 ok(flags == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected flags %#x.\n", flags);
4018 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4019 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
4021 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4022 ok(hr == S_OK, "Failed to get output info, hr %#x.\n", hr);
4024 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
4025 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4027 hr = MFCreateSample(&client_sample);
4028 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4030 hr = IMFSample_AddBuffer(client_sample, media_buffer);
4031 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
4032 IMFMediaBuffer_Release(media_buffer);
4034 status = 0;
4035 memset(&buffer, 0, sizeof(buffer));
4036 buffer.pSample = client_sample;
4037 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4038 ok(hr == S_OK, "Failed to get output, hr %#x.\n", hr);
4039 EXPECT_REF(sample, 1);
4041 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4042 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Failed to get output, hr %#x.\n", hr);
4044 /* Flushing. */
4045 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4046 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4047 EXPECT_REF(sample, 2);
4049 hr = IMFTransform_ProcessMessage(copier, MFT_MESSAGE_COMMAND_FLUSH, 0);
4050 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
4051 EXPECT_REF(sample, 1);
4053 IMFSample_Release(sample);
4054 IMFSample_Release(client_sample);
4056 IMFMediaType_Release(mediatype);
4057 IMFTransform_Release(copier);
4060 static void sample_copier_process(IMFTransform *copier, IMFMediaBuffer *input_buffer,
4061 IMFMediaBuffer *output_buffer)
4063 IMFSample *input_sample, *output_sample;
4064 MFT_OUTPUT_DATA_BUFFER buffer;
4065 DWORD status;
4066 HRESULT hr;
4068 hr = MFCreateSample(&input_sample);
4069 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4071 hr = MFCreateSample(&output_sample);
4072 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4074 hr = IMFSample_AddBuffer(input_sample, input_buffer);
4075 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4077 hr = IMFSample_AddBuffer(output_sample, output_buffer);
4078 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4080 hr = IMFTransform_ProcessInput(copier, 0, input_sample, 0);
4081 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4083 status = 0;
4084 memset(&buffer, 0, sizeof(buffer));
4085 buffer.pSample = output_sample;
4086 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4087 ok(hr == S_OK, "Failed to get output, hr %#x.\n", hr);
4089 IMFSample_Release(input_sample);
4090 IMFSample_Release(output_sample);
4093 static void test_sample_copier_output_processing(void)
4095 IMFMediaBuffer *input_buffer, *output_buffer;
4096 MFT_OUTPUT_STREAM_INFO output_info;
4097 IMFMediaType *mediatype;
4098 IMFTransform *copier;
4099 DWORD max_length;
4100 HRESULT hr;
4101 BYTE *ptr;
4103 hr = MFCreateSampleCopierMFT(&copier);
4104 ok(hr == S_OK, "Failed to create sample copier, hr %#x.\n", hr);
4106 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
4107 hr = MFCreateMediaType(&mediatype);
4108 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4110 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4111 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4113 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
4114 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4116 hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16);
4117 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4119 hr = IMFTransform_SetInputType(copier, 0, mediatype, 0);
4120 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4122 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
4123 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4125 /* Source and destination are linear buffers, destination is twice as large. */
4126 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4127 ok(hr == S_OK, "Failed to get output info, hr %#x.\n", hr);
4129 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &output_buffer);
4130 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4132 hr = IMFMediaBuffer_Lock(output_buffer, &ptr, &max_length, NULL);
4133 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4134 memset(ptr, 0xcc, max_length);
4135 hr = IMFMediaBuffer_Unlock(output_buffer);
4136 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4138 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &input_buffer);
4139 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4141 hr = IMFMediaBuffer_Lock(input_buffer, &ptr, &max_length, NULL);
4142 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4143 memset(ptr, 0xaa, max_length);
4144 hr = IMFMediaBuffer_Unlock(input_buffer);
4145 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4146 hr = IMFMediaBuffer_SetCurrentLength(input_buffer, 4);
4147 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4149 sample_copier_process(copier, input_buffer, output_buffer);
4151 hr = IMFMediaBuffer_Lock(output_buffer, &ptr, &max_length, NULL);
4152 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4153 ok(ptr[0] == 0xaa && ptr[4] == 0xcc, "Unexpected buffer contents.\n");
4155 hr = IMFMediaBuffer_Unlock(output_buffer);
4156 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4158 IMFMediaType_Release(mediatype);
4159 IMFTransform_Release(copier);
4162 static void test_MFGetTopoNodeCurrentType(void)
4164 IMFMediaType *media_type, *media_type2;
4165 IMFTopologyNode *node;
4166 HRESULT hr;
4168 /* Tee node. */
4169 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
4170 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
4172 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
4173 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4175 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4176 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4178 hr = MFCreateMediaType(&media_type2);
4179 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4181 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4182 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4184 /* Input type returned, if set. */
4185 hr = IMFTopologyNode_SetInputPrefType(node, 0, media_type2);
4186 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4188 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4189 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4190 ok(media_type == media_type2, "Unexpected pointer.\n");
4191 IMFMediaType_Release(media_type);
4193 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
4194 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4196 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4197 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4199 /* Set second output. */
4200 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
4201 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4203 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4204 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4206 hr = IMFTopologyNode_SetOutputPrefType(node, 1, NULL);
4207 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4209 /* Set first output. */
4210 hr = IMFTopologyNode_SetOutputPrefType(node, 0, media_type2);
4211 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4213 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4215 ok(media_type == media_type2, "Unexpected pointer.\n");
4216 IMFMediaType_Release(media_type);
4218 hr = IMFTopologyNode_SetOutputPrefType(node, 0, NULL);
4219 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4221 /* Set primary output. */
4222 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
4223 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4225 hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_PRIMARYOUTPUT, 1);
4226 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4228 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4229 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4230 ok(media_type == media_type2, "Unexpected pointer.\n");
4231 IMFMediaType_Release(media_type);
4233 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
4234 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4235 ok(media_type == media_type2, "Unexpected pointer.\n");
4236 IMFMediaType_Release(media_type);
4238 IMFTopologyNode_Release(node);
4239 IMFMediaType_Release(media_type2);
4242 START_TEST(mf)
4244 test_topology();
4245 test_topology_tee_node();
4246 test_topology_loader();
4247 test_MFGetService();
4248 test_sequencer_source();
4249 test_media_session();
4250 test_MFShutdownObject();
4251 test_presentation_clock();
4252 test_sample_grabber();
4253 test_video_processor();
4254 test_quality_manager();
4255 test_sar();
4256 test_evr();
4257 test_MFCreateSimpleTypeHandler();
4258 test_MFGetSupportedMimeTypes();
4259 test_MFGetSupportedSchemes();
4260 test_sample_copier();
4261 test_sample_copier_output_processing();
4262 test_MFGetTopoNodeCurrentType();