mf: Attempt to create mmdevapi device on SAR creation.
[wine.git] / dlls / mf / tests / mf.c
blob4f2936210287c8f2838cb38a9d81b3511a597560
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>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
29 #include "initguid.h"
30 #include "ole2.h"
32 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
33 DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
34 DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
36 #undef INITGUID
37 #include <guiddef.h>
38 #include "mfapi.h"
39 #include "mferror.h"
40 #include "mfidl.h"
41 #include "mmdeviceapi.h"
43 #include "wine/test.h"
45 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
46 static void _expect_ref(IUnknown* obj, ULONG expected_refcount, int line)
48 ULONG refcount;
49 IUnknown_AddRef(obj);
50 refcount = IUnknown_Release(obj);
51 ok_(__FILE__, line)(refcount == expected_refcount, "Unexpected refcount %d, expected %d.\n", refcount,
52 expected_refcount);
55 static WCHAR *load_resource(const WCHAR *name)
57 static WCHAR pathW[MAX_PATH];
58 DWORD written;
59 HANDLE file;
60 HRSRC res;
61 void *ptr;
63 GetTempPathW(ARRAY_SIZE(pathW), pathW);
64 lstrcatW(pathW, name);
66 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
67 NULL, CREATE_ALWAYS, 0, 0);
68 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
69 wine_dbgstr_w(pathW), GetLastError());
71 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
72 ok(res != 0, "couldn't find resource\n");
73 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
74 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
75 &written, NULL);
76 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
77 "couldn't write resource\n" );
78 CloseHandle(file);
80 return pathW;
83 static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
85 if (IsEqualIID(riid, &IID_IUnknown))
87 *obj = iface;
88 IUnknown_AddRef(iface);
89 return S_OK;
92 *obj = NULL;
93 return E_NOINTERFACE;
96 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
98 return 2;
101 static ULONG WINAPI test_unk_Release(IUnknown *iface)
103 return 1;
106 static const IUnknownVtbl test_unk_vtbl =
108 test_unk_QueryInterface,
109 test_unk_AddRef,
110 test_unk_Release,
113 static void test_topology(void)
115 IMFCollection *collection, *collection2;
116 IUnknown test_unk2 = { &test_unk_vtbl };
117 IUnknown test_unk = { &test_unk_vtbl };
118 IMFTopologyNode *node, *node2, *node3;
119 IMFMediaType *mediatype, *mediatype2;
120 IMFTopology *topology, *topology2;
121 MF_TOPOLOGY_TYPE node_type;
122 UINT32 count, index;
123 IUnknown *object;
124 WORD node_count;
125 DWORD size;
126 HRESULT hr;
127 TOPOID id;
129 hr = MFCreateTopology(NULL);
130 ok(hr == E_POINTER, "got %#x\n", hr);
132 hr = MFCreateTopology(&topology);
133 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
134 hr = IMFTopology_GetTopologyID(topology, &id);
135 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
136 ok(id == 1, "Unexpected id.\n");
138 hr = MFCreateTopology(&topology2);
139 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
140 hr = IMFTopology_GetTopologyID(topology2, &id);
141 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
142 ok(id == 2, "Unexpected id.\n");
144 IMFTopology_Release(topology);
146 hr = MFCreateTopology(&topology);
147 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
148 hr = IMFTopology_GetTopologyID(topology, &id);
149 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
150 ok(id == 3, "Unexpected id.\n");
152 IMFTopology_Release(topology2);
154 /* No attributes by default. */
155 for (node_type = MF_TOPOLOGY_OUTPUT_NODE; node_type < MF_TOPOLOGY_TEE_NODE; ++node_type)
157 hr = MFCreateTopologyNode(node_type, &node);
158 ok(hr == S_OK, "Failed to create a node for type %d, hr %#x.\n", node_type, hr);
159 hr = IMFTopologyNode_GetCount(node, &count);
160 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
161 ok(!count, "Unexpected attribute count %u.\n", count);
162 IMFTopologyNode_Release(node);
165 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, NULL);
166 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
168 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
169 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
171 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
172 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
174 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
175 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
176 ok(((id >> 32) == GetCurrentProcessId()) && !!(id & 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id));
178 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
179 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
181 hr = IMFTopology_GetNodeCount(topology, NULL);
182 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
184 hr = IMFTopology_AddNode(topology, NULL);
185 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
187 node_count = 1;
188 hr = IMFTopology_GetNodeCount(topology, &node_count);
189 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
190 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
192 /* Same id, different nodes. */
193 hr = IMFTopology_AddNode(topology, node);
194 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
196 node_count = 0;
197 hr = IMFTopology_GetNodeCount(topology, &node_count);
198 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
199 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
201 hr = IMFTopology_AddNode(topology, node2);
202 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
203 IMFTopologyNode_Release(node2);
205 hr = IMFTopology_GetNodeByID(topology, id, &node2);
206 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
207 ok(node2 == node, "Unexpected node.\n");
208 IMFTopologyNode_Release(node2);
210 /* Change node id, add it again. */
211 hr = IMFTopologyNode_SetTopoNodeID(node, ++id);
212 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
214 hr = IMFTopology_GetNodeByID(topology, id, &node2);
215 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
216 ok(node2 == node, "Unexpected node.\n");
217 IMFTopologyNode_Release(node2);
219 hr = IMFTopology_GetNodeByID(topology, id + 1, &node2);
220 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
222 hr = IMFTopology_AddNode(topology, node);
223 ok(hr == E_INVALIDARG, "Failed to add a node, hr %#x.\n", hr);
225 hr = IMFTopology_GetNode(topology, 0, &node2);
226 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
227 ok(node2 == node, "Unexpected node.\n");
228 IMFTopologyNode_Release(node2);
230 hr = IMFTopology_GetNode(topology, 1, NULL);
231 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
233 hr = IMFTopology_GetNode(topology, 1, &node2);
234 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
236 hr = IMFTopology_GetNode(topology, -2, &node2);
237 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
239 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
240 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
241 hr = IMFTopology_AddNode(topology, node2);
242 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
243 IMFTopologyNode_Release(node2);
245 node_count = 0;
246 hr = IMFTopology_GetNodeCount(topology, &node_count);
247 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
248 ok(node_count == 2, "Unexpected node count %u.\n", node_count);
250 /* Remove with detached node, existing id. */
251 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
252 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
253 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
254 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
255 hr = IMFTopology_RemoveNode(topology, node2);
256 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
257 IMFTopologyNode_Release(node2);
259 hr = IMFTopology_RemoveNode(topology, node);
260 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
262 node_count = 0;
263 hr = IMFTopology_GetNodeCount(topology, &node_count);
264 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
265 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
267 hr = IMFTopology_Clear(topology);
268 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
270 node_count = 1;
271 hr = IMFTopology_GetNodeCount(topology, &node_count);
272 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
273 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
275 hr = IMFTopology_Clear(topology);
276 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
278 hr = IMFTopologyNode_SetTopoNodeID(node, 123);
279 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
281 IMFTopologyNode_Release(node);
283 /* Change id for attached node. */
284 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
285 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
287 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
288 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
290 hr = IMFTopology_AddNode(topology, node);
291 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
293 hr = IMFTopology_AddNode(topology, node2);
294 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
296 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
297 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
299 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
300 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
302 hr = IMFTopology_GetNodeByID(topology, id, &node3);
303 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
304 ok(node3 == node, "Unexpected node.\n");
305 IMFTopologyNode_Release(node3);
307 IMFTopologyNode_Release(node);
308 IMFTopologyNode_Release(node2);
310 /* Source/output collections. */
311 hr = IMFTopology_Clear(topology);
312 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
314 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
315 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
317 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
318 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
319 ok(!!collection, "Unexpected object pointer.\n");
321 hr = IMFTopology_GetSourceNodeCollection(topology, &collection2);
322 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
323 ok(!!collection2, "Unexpected object pointer.\n");
324 ok(collection2 != collection, "Expected cloned collection.\n");
326 hr = IMFCollection_GetElementCount(collection, &size);
327 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
328 ok(!size, "Unexpected item count.\n");
330 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
331 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
333 hr = IMFCollection_GetElementCount(collection, &size);
334 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
335 ok(size == 1, "Unexpected item count.\n");
337 hr = IMFCollection_GetElementCount(collection2, &size);
338 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
339 ok(!size, "Unexpected item count.\n");
341 IMFCollection_Release(collection2);
342 IMFCollection_Release(collection);
344 /* Add some nodes. */
345 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
346 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
348 hr = IMFTopology_GetOutputNodeCollection(topology, NULL);
349 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
351 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
352 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
353 hr = IMFTopology_AddNode(topology, node);
354 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
355 IMFTopologyNode_Release(node);
357 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
358 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
359 ok(!!collection, "Unexpected object pointer.\n");
360 hr = IMFCollection_GetElementCount(collection, &size);
361 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
362 ok(size == 1, "Unexpected item count.\n");
363 IMFCollection_Release(collection);
365 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
366 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
367 hr = IMFTopology_AddNode(topology, node);
368 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
369 IMFTopologyNode_Release(node);
371 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
372 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
373 ok(!!collection, "Unexpected object pointer.\n");
374 hr = IMFCollection_GetElementCount(collection, &size);
375 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
376 ok(size == 1, "Unexpected item count.\n");
377 IMFCollection_Release(collection);
379 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
380 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
381 hr = IMFTopology_AddNode(topology, node);
382 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
383 IMFTopologyNode_Release(node);
385 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
386 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
387 ok(!!collection, "Unexpected object pointer.\n");
388 hr = IMFCollection_GetElementCount(collection, &size);
389 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
390 ok(size == 1, "Unexpected item count.\n");
391 IMFCollection_Release(collection);
393 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
394 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
395 hr = IMFTopology_AddNode(topology, node);
396 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
398 /* Associated object. */
399 hr = IMFTopologyNode_SetObject(node, NULL);
400 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
402 hr = IMFTopologyNode_GetObject(node, NULL);
403 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
405 object = (void *)0xdeadbeef;
406 hr = IMFTopologyNode_GetObject(node, &object);
407 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
408 ok(!object, "Unexpected object %p.\n", object);
410 hr = IMFTopologyNode_SetObject(node, &test_unk);
411 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
413 hr = IMFTopologyNode_GetObject(node, &object);
414 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
415 ok(object == &test_unk, "Unexpected object %p.\n", object);
416 IUnknown_Release(object);
418 hr = IMFTopologyNode_SetObject(node, &test_unk2);
419 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
421 hr = IMFTopologyNode_GetCount(node, &count);
422 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
423 ok(count == 0, "Unexpected attribute count %u.\n", count);
425 hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &MF_TOPONODE_TRANSFORM_OBJECTID);
426 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
428 hr = IMFTopologyNode_SetObject(node, NULL);
429 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
431 object = (void *)0xdeadbeef;
432 hr = IMFTopologyNode_GetObject(node, &object);
433 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
434 ok(!object, "Unexpected object %p.\n", object);
436 hr = IMFTopologyNode_GetCount(node, &count);
437 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
438 ok(count == 1, "Unexpected attribute count %u.\n", count);
440 /* Preferred stream types. */
441 hr = IMFTopologyNode_GetInputCount(node, &count);
442 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
443 ok(count == 0, "Unexpected count %u.\n", count);
445 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype);
446 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
448 hr = MFCreateMediaType(&mediatype);
449 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
451 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
452 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
454 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
455 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
456 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
457 IMFMediaType_Release(mediatype2);
459 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
460 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
462 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
463 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
464 ok(!mediatype2, "Unexpected mediatype instance.\n");
466 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
467 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
469 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
470 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
472 hr = IMFTopologyNode_GetInputCount(node, &count);
473 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
474 ok(count == 2, "Unexpected count %u.\n", count);
476 hr = IMFTopologyNode_GetOutputCount(node, &count);
477 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
478 ok(count == 0, "Unexpected count %u.\n", count);
480 hr = IMFTopologyNode_SetOutputPrefType(node, 0, mediatype);
481 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
483 IMFTopologyNode_Release(node);
485 /* Source node. */
486 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
487 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
489 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
490 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
492 hr = IMFTopologyNode_SetOutputPrefType(node, 2, mediatype);
493 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
495 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
496 ok(hr == E_FAIL, "Failed to get preferred type, hr %#x.\n", hr);
497 ok(!mediatype2, "Unexpected mediatype instance.\n");
499 hr = IMFTopologyNode_GetOutputCount(node, &count);
500 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
501 ok(count == 3, "Unexpected count %u.\n", count);
503 IMFTopologyNode_Release(node);
505 /* Tee node. */
506 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
507 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
509 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
510 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
512 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
513 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
514 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
515 IMFMediaType_Release(mediatype2);
517 hr = IMFTopologyNode_GetInputCount(node, &count);
518 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
519 ok(count == 0, "Unexpected count %u.\n", count);
521 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
522 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
524 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
525 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
527 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype);
528 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
530 hr = IMFTopologyNode_GetInputCount(node, &count);
531 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
532 ok(count == 0, "Unexpected count %u.\n", count);
534 hr = IMFTopologyNode_GetOutputCount(node, &count);
535 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
536 ok(count == 5, "Unexpected count %u.\n", count);
538 IMFTopologyNode_Release(node);
540 /* Transform node. */
541 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
542 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
544 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
545 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
547 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype);
548 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
550 hr = IMFTopologyNode_GetInputCount(node, &count);
551 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
552 ok(count == 4, "Unexpected count %u.\n", count);
554 hr = IMFTopologyNode_GetOutputCount(node, &count);
555 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
556 ok(count == 5, "Unexpected count %u.\n", count);
558 IMFTopologyNode_Release(node);
560 IMFMediaType_Release(mediatype);
562 hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
563 ok(hr == S_OK || broken(hr == E_FAIL) /* before Win8 */, "Failed to get output node collection, hr %#x.\n", hr);
564 if (SUCCEEDED(hr))
566 ok(!!collection, "Unexpected object pointer.\n");
567 hr = IMFCollection_GetElementCount(collection, &size);
568 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
569 ok(size == 1, "Unexpected item count.\n");
570 IMFCollection_Release(collection);
573 IMFTopology_Release(topology);
575 /* Connect nodes. */
576 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
577 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
579 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
580 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
582 EXPECT_REF(node, 1);
583 EXPECT_REF(node2, 1);
585 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
586 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
588 EXPECT_REF(node, 2);
589 EXPECT_REF(node2, 2);
591 IMFTopologyNode_Release(node);
593 EXPECT_REF(node, 1);
594 EXPECT_REF(node2, 2);
596 IMFTopologyNode_Release(node2);
598 EXPECT_REF(node, 1);
599 EXPECT_REF(node2, 1);
601 hr = IMFTopologyNode_GetNodeType(node2, &node_type);
602 ok(hr == S_OK, "Failed to get node type, hr %#x.\n", hr);
604 IMFTopologyNode_Release(node);
606 /* Connect within topology. */
607 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
608 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
610 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
611 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
613 hr = MFCreateTopology(&topology);
614 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
616 hr = IMFTopology_AddNode(topology, node);
617 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
619 hr = IMFTopology_AddNode(topology, node2);
620 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
622 EXPECT_REF(node, 2);
623 EXPECT_REF(node2, 2);
625 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
626 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
628 EXPECT_REF(node, 3);
629 EXPECT_REF(node2, 3);
631 hr = IMFTopology_Clear(topology);
632 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
634 EXPECT_REF(node, 1);
635 EXPECT_REF(node2, 1);
637 /* Removing connected node breaks connection. */
638 hr = IMFTopology_AddNode(topology, node);
639 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
641 hr = IMFTopology_AddNode(topology, node2);
642 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
644 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
645 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
647 hr = IMFTopology_RemoveNode(topology, node);
648 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
650 EXPECT_REF(node, 1);
651 EXPECT_REF(node2, 2);
653 hr = IMFTopologyNode_GetOutput(node, 0, &node3, &index);
654 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
656 hr = IMFTopology_AddNode(topology, node);
657 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
659 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
660 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
662 hr = IMFTopology_RemoveNode(topology, node2);
663 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
665 EXPECT_REF(node, 2);
666 EXPECT_REF(node2, 1);
668 IMFTopologyNode_Release(node);
669 IMFTopologyNode_Release(node2);
671 /* Cloning nodes of different types. */
672 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
673 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
675 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
676 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
678 hr = IMFTopologyNode_CloneFrom(node, node2);
679 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
681 IMFTopologyNode_Release(node2);
683 /* Cloning preferred types. */
684 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
685 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
687 hr = MFCreateMediaType(&mediatype);
688 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
690 hr = IMFTopologyNode_SetOutputPrefType(node2, 0, mediatype);
691 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
693 /* Vista checks for additional attributes. */
694 hr = IMFTopologyNode_CloneFrom(node, node2);
695 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
697 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
698 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
699 ok(mediatype == mediatype2, "Unexpected media type.\n");
701 IMFMediaType_Release(mediatype2);
702 IMFMediaType_Release(mediatype);
704 IMFTopologyNode_Release(node2);
706 /* Existing preferred types are not cleared. */
707 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
708 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
710 hr = IMFTopologyNode_GetOutputCount(node, &count);
711 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
712 ok(count == 1, "Unexpected output count.\n");
714 hr = IMFTopologyNode_CloneFrom(node, node2);
715 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
717 hr = IMFTopologyNode_GetOutputCount(node, &count);
718 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
719 ok(count == 1, "Unexpected output count.\n");
721 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
722 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
723 ok(!!mediatype2, "Unexpected media type.\n");
724 IMFMediaType_Release(mediatype2);
726 hr = IMFTopologyNode_CloneFrom(node2, node);
727 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
729 hr = IMFTopologyNode_GetOutputCount(node2, &count);
730 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
731 ok(count == 1, "Unexpected output count.\n");
733 IMFTopologyNode_Release(node2);
734 IMFTopologyNode_Release(node);
736 IMFTopology_Release(topology);
739 static HRESULT WINAPI test_getservice_QI(IMFGetService *iface, REFIID riid, void **obj)
741 if (IsEqualIID(riid, &IID_IMFGetService) || IsEqualIID(riid, &IID_IUnknown))
743 *obj = iface;
744 return S_OK;
747 *obj = NULL;
748 return E_NOINTERFACE;
751 static ULONG WINAPI test_getservice_AddRef(IMFGetService *iface)
753 return 2;
756 static ULONG WINAPI test_getservice_Release(IMFGetService *iface)
758 return 1;
761 static HRESULT WINAPI test_getservice_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
763 *obj = (void *)0xdeadbeef;
764 return 0x83eddead;
767 static const IMFGetServiceVtbl testmfgetservicevtbl =
769 test_getservice_QI,
770 test_getservice_AddRef,
771 test_getservice_Release,
772 test_getservice_GetService,
775 static IMFGetService test_getservice = { &testmfgetservicevtbl };
777 static HRESULT WINAPI testservice_QI(IUnknown *iface, REFIID riid, void **obj)
779 if (IsEqualIID(riid, &IID_IUnknown))
781 *obj = iface;
782 return S_OK;
785 *obj = NULL;
787 if (IsEqualIID(riid, &IID_IMFGetService))
788 return 0x82eddead;
790 return E_NOINTERFACE;
793 static HRESULT WINAPI testservice2_QI(IUnknown *iface, REFIID riid, void **obj)
795 if (IsEqualIID(riid, &IID_IUnknown))
797 *obj = iface;
798 return S_OK;
801 if (IsEqualIID(riid, &IID_IMFGetService))
803 *obj = &test_getservice;
804 return S_OK;
807 *obj = NULL;
808 return E_NOINTERFACE;
811 static ULONG WINAPI testservice_AddRef(IUnknown *iface)
813 return 2;
816 static ULONG WINAPI testservice_Release(IUnknown *iface)
818 return 1;
821 static const IUnknownVtbl testservicevtbl =
823 testservice_QI,
824 testservice_AddRef,
825 testservice_Release,
828 static const IUnknownVtbl testservice2vtbl =
830 testservice2_QI,
831 testservice_AddRef,
832 testservice_Release,
835 static IUnknown testservice = { &testservicevtbl };
836 static IUnknown testservice2 = { &testservice2vtbl };
838 static void test_MFGetService(void)
840 IUnknown *unk;
841 HRESULT hr;
843 hr = MFGetService(NULL, NULL, NULL, NULL);
844 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
846 unk = (void *)0xdeadbeef;
847 hr = MFGetService(NULL, NULL, NULL, (void **)&unk);
848 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
849 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
851 hr = MFGetService(&testservice, NULL, NULL, NULL);
852 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
854 unk = (void *)0xdeadbeef;
855 hr = MFGetService(&testservice, NULL, NULL, (void **)&unk);
856 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
857 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
859 unk = NULL;
860 hr = MFGetService(&testservice2, NULL, NULL, (void **)&unk);
861 ok(hr == 0x83eddead, "Unexpected return value %#x.\n", hr);
862 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
865 static void test_sequencer_source(void)
867 IMFMediaSourceTopologyProvider *provider;
868 IMFSequencerSource *seq_source;
869 HRESULT hr;
871 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
872 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
874 hr = MFCreateSequencerSource(NULL, &seq_source);
875 ok(hr == S_OK, "Failed to create sequencer source, hr %#x.\n", hr);
877 hr = IMFSequencerSource_QueryInterface(seq_source, &IID_IMFMediaSourceTopologyProvider, (void **)&provider);
878 ok(hr == S_OK, "Failed to get provider interface, hr %#x.\n", hr);
879 IMFMediaSourceTopologyProvider_Release(provider);
881 IMFSequencerSource_Release(seq_source);
883 hr = MFShutdown();
884 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
887 struct test_callback
889 IMFAsyncCallback IMFAsyncCallback_iface;
892 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
894 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
895 IsEqualIID(riid, &IID_IUnknown))
897 *obj = iface;
898 IMFAsyncCallback_AddRef(iface);
899 return S_OK;
902 *obj = NULL;
903 return E_NOINTERFACE;
906 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
908 return 2;
911 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
913 return 1;
916 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
918 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
919 return E_NOTIMPL;
922 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
924 ok(result != NULL, "Unexpected result object.\n");
926 return E_NOTIMPL;
929 static const IMFAsyncCallbackVtbl testcallbackvtbl =
931 testcallback_QueryInterface,
932 testcallback_AddRef,
933 testcallback_Release,
934 testcallback_GetParameters,
935 testcallback_Invoke,
938 static void init_test_callback(struct test_callback *callback)
940 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
943 static void test_session_events(IMFMediaSession *session)
945 struct test_callback callback, callback2;
946 IMFAsyncResult *result;
947 IMFMediaEvent *event;
948 HRESULT hr;
950 init_test_callback(&callback);
951 init_test_callback(&callback2);
953 hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event);
954 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
956 /* Async case. */
957 hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL);
958 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
960 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
961 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
963 /* Same callback, same state. */
964 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
965 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
967 /* Same callback, different state. */
968 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
969 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
971 /* Different callback, same state. */
972 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session);
973 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
975 /* Different callback, different state. */
976 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
977 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
979 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
980 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
982 hr = IMFMediaSession_EndGetEvent(session, result, &event);
983 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
985 /* Shutdown behavior. */
986 hr = IMFMediaSession_Shutdown(session);
987 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
990 static void test_media_session(void)
992 IMFRateControl *rate_control, *rate_control2;
993 IMFLocalMFTRegistration *local_reg;
994 MFCLOCK_PROPERTIES clock_props;
995 IMFRateSupport *rate_support;
996 IMFAttributes *attributes;
997 IMFMediaSession *session;
998 IMFTopology *topology;
999 PROPVARIANT propvar;
1000 IMFGetService *gs;
1001 IMFClock *clock;
1002 IUnknown *unk;
1003 HRESULT hr;
1004 float rate;
1005 DWORD caps;
1006 BOOL thin;
1008 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1009 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1011 hr = MFCreateMediaSession(NULL, &session);
1012 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1014 hr = IMFMediaSession_QueryInterface(session, &IID_IMFAttributes, (void **)&unk);
1015 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1017 hr = IMFMediaSession_QueryInterface(session, &IID_IMFGetService, (void **)&gs);
1018 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
1020 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support);
1021 ok(hr == S_OK, "Failed to get rate support interface, hr %#x.\n", hr);
1023 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, (void **)&rate_control);
1024 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
1026 hr = IMFGetService_GetService(gs, &MF_LOCAL_MFT_REGISTRATION_SERVICE, &IID_IMFLocalMFTRegistration,
1027 (void **)&local_reg);
1028 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get registration service, hr %#x.\n", hr);
1029 if (SUCCEEDED(hr))
1030 IMFLocalMFTRegistration_Release(local_reg);
1032 hr = IMFRateSupport_QueryInterface(rate_support, &IID_IMFMediaSession, (void **)&unk);
1033 ok(hr == S_OK, "Failed to get session interface, hr %#x.\n", hr);
1034 ok(unk == (IUnknown *)session, "Unexpected pointer.\n");
1035 IUnknown_Release(unk);
1037 hr = IMFRateControl_GetRate(rate_control, NULL, NULL);
1038 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1040 rate = 0.0f;
1041 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
1042 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1043 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1045 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
1046 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1048 thin = TRUE;
1049 rate = 0.0f;
1050 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1051 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1052 ok(!thin, "Unexpected thinning.\n");
1053 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1055 hr = IMFMediaSession_GetClock(session, &clock);
1056 ok(hr == S_OK, "Failed to get clock, hr %#x.\n", hr);
1058 hr = IMFClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control2);
1059 ok(hr == S_OK, "Failed to get rate control, hr %#x.\n", hr);
1061 rate = 0.0f;
1062 hr = IMFRateControl_GetRate(rate_control2, NULL, &rate);
1063 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1064 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1066 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.5f);
1067 todo_wine
1068 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
1070 IMFRateControl_Release(rate_control2);
1072 hr = IMFClock_GetProperties(clock, &clock_props);
1073 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1074 IMFClock_Release(clock);
1076 IMFRateControl_Release(rate_control);
1077 IMFRateSupport_Release(rate_support);
1079 IMFGetService_Release(gs);
1081 IMFMediaSession_Release(session);
1083 hr = MFCreateMediaSession(NULL, &session);
1084 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1086 hr = IMFMediaSession_Shutdown(session);
1087 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1089 hr = IMFMediaSession_ClearTopologies(session);
1090 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1092 hr = IMFMediaSession_Start(session, &GUID_NULL, NULL);
1093 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1095 propvar.vt = VT_EMPTY;
1096 hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar);
1097 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1099 hr = IMFMediaSession_Pause(session);
1100 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1102 hr = IMFMediaSession_Stop(session);
1103 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1105 hr = IMFMediaSession_Close(session);
1106 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1108 hr = IMFMediaSession_GetClock(session, &clock);
1109 ok(hr == MF_E_SHUTDOWN || broken(hr == E_UNEXPECTED) /* Win7 */, "Unexpected hr %#x.\n", hr);
1111 hr = IMFMediaSession_GetSessionCapabilities(session, &caps);
1112 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1114 hr = IMFMediaSession_GetSessionCapabilities(session, NULL);
1115 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1117 hr = IMFMediaSession_GetFullTopology(session, MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology);
1118 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1120 hr = IMFMediaSession_Shutdown(session);
1121 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1123 IMFMediaSession_Release(session);
1125 /* Custom topology loader, GUID is not registered. */
1126 hr = MFCreateAttributes(&attributes, 1);
1127 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
1129 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_TOPOLOADER, &MF_SESSION_TOPOLOADER);
1130 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1132 hr = MFCreateMediaSession(attributes, &session);
1133 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1134 IMFMediaSession_Release(session);
1136 /* Disabled quality manager. */
1137 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_QUALITY_MANAGER, &GUID_NULL);
1138 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1140 hr = MFCreateMediaSession(attributes, &session);
1141 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1142 IMFMediaSession_Release(session);
1144 IMFAttributes_Release(attributes);
1146 /* Basic events behavior. */
1147 hr = MFCreateMediaSession(NULL, &session);
1148 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1150 test_session_events(session);
1152 IMFMediaSession_Release(session);
1154 hr = MFShutdown();
1155 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1158 static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid,
1159 void **obj)
1161 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
1162 IsEqualIID(riid, &IID_IMFClockStateSink) ||
1163 IsEqualIID(riid, &IID_IUnknown))
1165 *obj = iface;
1166 IMFSampleGrabberSinkCallback_AddRef(iface);
1167 return S_OK;
1170 *obj = NULL;
1171 return E_NOINTERFACE;
1174 static ULONG WINAPI test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
1176 return 2;
1179 static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
1181 return 1;
1184 static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME systime,
1185 LONGLONG offset)
1187 return E_NOTIMPL;
1190 static HRESULT WINAPI test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1192 return E_NOTIMPL;
1195 static HRESULT WINAPI test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1197 return E_NOTIMPL;
1200 static HRESULT WINAPI test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1202 return E_NOTIMPL;
1205 static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME systime, float rate)
1207 return E_NOTIMPL;
1210 static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
1211 IMFPresentationClock *clock)
1213 return E_NOTIMPL;
1216 static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
1217 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
1219 return E_NOTIMPL;
1222 static HRESULT WINAPI test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
1224 return E_NOTIMPL;
1227 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl =
1229 test_grabber_callback_QueryInterface,
1230 test_grabber_callback_AddRef,
1231 test_grabber_callback_Release,
1232 test_grabber_callback_OnClockStart,
1233 test_grabber_callback_OnClockStop,
1234 test_grabber_callback_OnClockPause,
1235 test_grabber_callback_OnClockRestart,
1236 test_grabber_callback_OnClockSetRate,
1237 test_grabber_callback_OnSetPresentationClock,
1238 test_grabber_callback_OnProcessSample,
1239 test_grabber_callback_OnShutdown,
1242 static void test_topology_loader(void)
1244 IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl };
1245 IMFTopology *topology, *topology2, *full_topology;
1246 IMFTopologyNode *src_node, *sink_node;
1247 IMFPresentationDescriptor *pd;
1248 IMFSourceResolver *resolver;
1249 IMFActivate *sink_activate;
1250 unsigned int count, value;
1251 IMFMediaType *media_type;
1252 IMFStreamDescriptor *sd;
1253 MF_OBJECT_TYPE obj_type;
1254 IMFMediaSource *source;
1255 IMFTopoLoader *loader;
1256 IMFByteStream *stream;
1257 IMFAttributes *attr;
1258 IMFMediaSink *sink;
1259 WCHAR *filename;
1260 BOOL selected;
1261 HRESULT hr;
1262 GUID guid;
1264 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1265 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1267 hr = MFCreateTopoLoader(NULL);
1268 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1270 hr = MFCreateTopoLoader(&loader);
1271 ok(hr == S_OK, "Failed to create topology loader, hr %#x.\n", hr);
1273 hr = MFCreateTopology(&topology);
1274 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
1276 /* Empty topology */
1277 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1278 todo_wine
1279 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1281 hr = MFCreateSourceResolver(&resolver);
1282 ok(hr == S_OK, "Failed to create source resolver, hr %#x.\n", hr);
1284 filename = load_resource(L"test.wav");
1286 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
1287 ok(hr == S_OK, "Failed to create file stream, hr %#x.\n", hr);
1289 IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attr);
1290 IMFAttributes_SetString(attr, &MF_BYTESTREAM_CONTENT_TYPE, L"audio/wav");
1291 IMFAttributes_Release(attr);
1293 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
1294 &obj_type, (IUnknown **)&source);
1295 ok(hr == S_OK || broken(FAILED(hr)) /* Vista */, "Failed to create source, hr %#x.\n", hr);
1296 if (FAILED(hr))
1297 return;
1299 hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
1300 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
1302 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
1303 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
1305 /* Add source node. */
1306 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
1307 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
1309 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
1310 ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
1312 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
1313 ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
1315 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
1316 ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
1318 hr = IMFTopology_AddNode(topology, src_node);
1319 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
1321 /* Source node only. */
1322 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1323 todo_wine
1324 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1326 /* Add grabber sink. */
1327 hr = MFCreateMediaType(&media_type);
1328 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1330 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1331 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1332 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
1333 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1335 hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate);
1336 ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
1338 IMFMediaType_Release(media_type);
1340 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
1341 ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr);
1343 hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate);
1344 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1345 hr = IMFTopology_AddNode(topology, sink_node);
1346 ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
1348 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1349 todo_wine
1350 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1352 hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
1353 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
1355 /* Sink was not resolved. */
1356 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1357 ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1359 hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
1360 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
1362 hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink);
1363 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1365 hr = IMFTopology_GetCount(topology, &count);
1366 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1367 ok(count == 0, "Unexpected count %u.\n", count);
1369 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1370 todo_wine
1371 ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
1372 ok(full_topology != topology, "Unexpected instance.\n");
1374 hr = IMFTopology_GetCount(topology, &count);
1375 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1376 ok(count == 0, "Unexpected count %u.\n", count);
1378 hr = IMFTopology_GetCount(full_topology, &count);
1379 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1380 todo_wine
1381 ok(count == 1, "Unexpected count %u.\n", count);
1383 hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL);
1384 todo_wine {
1385 ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr);
1386 ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid));
1388 value = 0xdeadbeef;
1389 hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
1390 todo_wine {
1391 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1392 ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
1394 hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
1395 ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
1396 ok(full_topology != topology2, "Unexpected instance.\n");
1398 IMFTopology_Release(topology2);
1399 IMFTopology_Release(full_topology);
1401 IMFMediaSource_Release(source);
1402 IMFSourceResolver_Release(resolver);
1403 IMFByteStream_Release(stream);
1404 IMFTopoLoader_Release(loader);
1406 hr = MFShutdown();
1407 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1410 static HRESULT WINAPI testshutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **obj)
1412 if (IsEqualIID(riid, &IID_IMFShutdown) ||
1413 IsEqualIID(riid, &IID_IUnknown))
1415 *obj = iface;
1416 IMFShutdown_AddRef(iface);
1417 return S_OK;
1420 *obj = NULL;
1421 return E_NOINTERFACE;
1424 static ULONG WINAPI testshutdown_AddRef(IMFShutdown *iface)
1426 return 2;
1429 static ULONG WINAPI testshutdown_Release(IMFShutdown *iface)
1431 return 1;
1434 static HRESULT WINAPI testshutdown_Shutdown(IMFShutdown *iface)
1436 return 0xdead;
1439 static HRESULT WINAPI testshutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status)
1441 ok(0, "Unexpected call.\n");
1442 return E_NOTIMPL;
1445 static const IMFShutdownVtbl testshutdownvtbl =
1447 testshutdown_QueryInterface,
1448 testshutdown_AddRef,
1449 testshutdown_Release,
1450 testshutdown_Shutdown,
1451 testshutdown_GetShutdownStatus,
1454 static void test_MFShutdownObject(void)
1456 IMFShutdown testshutdown = { &testshutdownvtbl };
1457 IUnknown testshutdown2 = { &testservicevtbl };
1458 HRESULT hr;
1460 hr = MFShutdownObject(NULL);
1461 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1463 hr = MFShutdownObject((IUnknown *)&testshutdown);
1464 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1466 hr = MFShutdownObject(&testshutdown2);
1467 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1470 enum clock_action
1472 CLOCK_START,
1473 CLOCK_STOP,
1474 CLOCK_PAUSE,
1477 static HRESULT WINAPI test_clock_sink_QueryInterface(IMFClockStateSink *iface, REFIID riid, void **obj)
1479 if (IsEqualIID(riid, &IID_IMFClockStateSink) ||
1480 IsEqualIID(riid, &IID_IUnknown))
1482 *obj = iface;
1483 IMFClockStateSink_AddRef(iface);
1484 return S_OK;
1487 *obj = NULL;
1488 return E_NOINTERFACE;
1491 static ULONG WINAPI test_clock_sink_AddRef(IMFClockStateSink *iface)
1493 return 2;
1496 static ULONG WINAPI test_clock_sink_Release(IMFClockStateSink *iface)
1498 return 1;
1501 static HRESULT WINAPI test_clock_sink_OnClockStart(IMFClockStateSink *iface, MFTIME system_time, LONGLONG offset)
1503 return E_NOTIMPL;
1506 static HRESULT WINAPI test_clock_sink_OnClockStop(IMFClockStateSink *iface, MFTIME system_time)
1508 return E_NOTIMPL;
1511 static HRESULT WINAPI test_clock_sink_OnClockPause(IMFClockStateSink *iface, MFTIME system_time)
1513 return E_NOTIMPL;
1516 static HRESULT WINAPI test_clock_sink_OnClockRestart(IMFClockStateSink *iface, MFTIME system_time)
1518 return E_NOTIMPL;
1521 static HRESULT WINAPI test_clock_sink_OnClockSetRate(IMFClockStateSink *iface, MFTIME system_time, float rate)
1523 return E_NOTIMPL;
1526 static const IMFClockStateSinkVtbl test_clock_sink_vtbl =
1528 test_clock_sink_QueryInterface,
1529 test_clock_sink_AddRef,
1530 test_clock_sink_Release,
1531 test_clock_sink_OnClockStart,
1532 test_clock_sink_OnClockStop,
1533 test_clock_sink_OnClockPause,
1534 test_clock_sink_OnClockRestart,
1535 test_clock_sink_OnClockSetRate,
1538 static void test_presentation_clock(void)
1540 static const struct clock_state_test
1542 enum clock_action action;
1543 MFCLOCK_STATE clock_state;
1544 MFCLOCK_STATE source_state;
1545 HRESULT hr;
1547 clock_state_change[] =
1549 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID },
1550 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_INVALIDREQUEST },
1551 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_CLOCK_STATE_ALREADY_SET },
1552 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1553 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1554 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
1555 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED, MF_E_CLOCK_STATE_ALREADY_SET },
1556 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
1557 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1558 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
1559 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_CLOCK_STATE_ALREADY_SET },
1560 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_INVALIDREQUEST },
1561 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1562 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
1563 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
1565 IMFClockStateSink test_sink = { &test_clock_sink_vtbl };
1566 IMFPresentationTimeSource *time_source;
1567 MFCLOCK_PROPERTIES props, props2;
1568 IMFRateControl *rate_control;
1569 IMFPresentationClock *clock;
1570 MFSHUTDOWN_STATUS status;
1571 IMFShutdown *shutdown;
1572 MFTIME systime, time;
1573 LONGLONG clock_time;
1574 MFCLOCK_STATE state;
1575 IMFTimer *timer;
1576 unsigned int i;
1577 DWORD value;
1578 float rate;
1579 HRESULT hr;
1580 BOOL thin;
1582 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1583 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1585 hr = MFCreatePresentationClock(&clock);
1586 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
1588 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control);
1589 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
1591 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
1592 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1594 hr = IMFPresentationClock_GetTimeSource(clock, NULL);
1595 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1597 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
1598 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1600 hr = IMFPresentationClock_GetClockCharacteristics(clock, NULL);
1601 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1603 hr = IMFPresentationClock_GetTime(clock, &time);
1604 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1606 hr = IMFPresentationClock_GetTime(clock, NULL);
1607 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1609 value = 1;
1610 hr = IMFPresentationClock_GetContinuityKey(clock, &value);
1611 ok(hr == S_OK, "Failed to get continuity key, hr %#x.\n", hr);
1612 ok(value == 0, "Unexpected value %u.\n", value);
1614 hr = IMFPresentationClock_GetProperties(clock, &props);
1615 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1617 hr = IMFPresentationClock_GetState(clock, 0, &state);
1618 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
1619 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
1621 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &clock_time, &systime);
1622 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1624 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, NULL, &systime);
1625 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1627 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, NULL);
1628 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1630 /* Sinks. */
1631 hr = IMFPresentationClock_AddClockStateSink(clock, NULL);
1632 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1634 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
1635 ok(hr == S_OK, "Failed to add a sink, hr %#x.\n", hr);
1637 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
1638 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1640 hr = IMFPresentationClock_RemoveClockStateSink(clock, NULL);
1641 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1643 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
1644 ok(hr == S_OK, "Failed to remove sink, hr %#x.\n", hr);
1646 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
1647 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1649 /* State change commands, time source is not set yet. */
1650 hr = IMFPresentationClock_Start(clock, 0);
1651 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1653 hr = IMFPresentationClock_Pause(clock);
1654 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1656 hr = IMFPresentationClock_Stop(clock);
1657 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1659 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1660 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1662 /* Set default time source. */
1663 hr = MFCreateSystemTimeSource(&time_source);
1664 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
1666 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
1667 ok(hr == S_OK, "Failed to get time source flags, hr %#x.\n", hr);
1668 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
1669 "Unexpected clock flags %#x.\n", value);
1671 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
1672 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
1674 hr = IMFPresentationTimeSource_GetProperties(time_source, &props2);
1675 ok(hr == S_OK, "Failed to get time source properties, hr %#x.\n", hr);
1677 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
1678 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
1679 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
1680 "Unexpected clock flags %#x.\n", value);
1682 hr = IMFPresentationClock_GetProperties(clock, &props);
1683 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
1684 ok(!memcmp(&props, &props2, sizeof(props)), "Unexpected clock properties.\n");
1686 /* State changes. */
1687 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
1689 switch (clock_state_change[i].action)
1691 case CLOCK_STOP:
1692 hr = IMFPresentationClock_Stop(clock);
1693 break;
1694 case CLOCK_PAUSE:
1695 hr = IMFPresentationClock_Pause(clock);
1696 break;
1697 case CLOCK_START:
1698 hr = IMFPresentationClock_Start(clock, 0);
1699 break;
1700 default:
1703 ok(hr == clock_state_change[i].hr, "%u: unexpected hr %#x.\n", i, hr);
1705 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
1706 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
1707 ok(state == clock_state_change[i].source_state, "%u: unexpected state %d.\n", i, state);
1709 hr = IMFPresentationClock_GetState(clock, 0, &state);
1710 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
1711 ok(state == clock_state_change[i].clock_state, "%u: unexpected state %d.\n", i, state);
1714 /* Clock time stamps. */
1715 hr = IMFPresentationClock_Start(clock, 10);
1716 ok(hr == S_OK, "Failed to start presentation clock, hr %#x.\n", hr);
1718 hr = IMFPresentationClock_Pause(clock);
1719 ok(hr == S_OK, "Failed to pause presentation clock, hr %#x.\n", hr);
1721 hr = IMFPresentationClock_GetTime(clock, &time);
1722 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
1724 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &clock_time, &systime);
1725 ok(hr == S_OK, "Failed to get time source time, hr %#x.\n", hr);
1726 ok(time == clock_time, "Unexpected clock time.\n");
1728 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, &systime);
1729 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
1730 ok(time == clock_time, "Unexpected clock time.\n");
1732 IMFPresentationTimeSource_Release(time_source);
1734 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
1735 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1737 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
1738 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1740 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1741 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1742 ok(rate == 1.0f, "Unexpected rate.\n");
1743 ok(!thin, "Unexpected thinning.\n");
1745 hr = IMFPresentationClock_GetState(clock, 0, &state);
1746 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
1747 ok(state == MFCLOCK_STATE_PAUSED, "Unexpected state %d.\n", state);
1749 hr = IMFPresentationClock_Start(clock, 0);
1750 ok(hr == S_OK, "Failed to stop, hr %#x.\n", hr);
1752 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1753 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1754 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1755 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1756 ok(rate == 0.0f, "Unexpected rate.\n");
1757 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.0f);
1758 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1759 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
1760 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1761 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.5f);
1762 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
1763 hr = IMFRateControl_SetRate(rate_control, TRUE, -1.0f);
1764 ok(hr == MF_E_THINNING_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1766 hr = IMFPresentationClock_GetState(clock, 0, &state);
1767 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
1768 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
1770 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1771 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1772 ok(rate == 0.5f, "Unexpected rate.\n");
1773 ok(!thin, "Unexpected thinning.\n");
1775 IMFRateControl_Release(rate_control);
1777 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFTimer, (void **)&timer);
1778 ok(hr == S_OK, "Failed to get timer interface, hr %#x.\n", hr);
1779 IMFTimer_Release(timer);
1781 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
1782 ok(hr == S_OK, "Failed to get shutdown interface, hr %#x.\n", hr);
1784 /* Shutdown behavior. */
1785 hr = IMFShutdown_GetShutdownStatus(shutdown, NULL);
1786 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1788 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1789 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1791 hr = IMFShutdown_Shutdown(shutdown);
1792 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1794 time_source = NULL;
1795 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
1796 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1797 ok(!!time_source, "Unexpected instance %p.\n", time_source);
1798 IMFPresentationTimeSource_Release(time_source);
1800 hr = IMFPresentationClock_GetTime(clock, &time);
1801 ok(hr == S_OK, "Failed to get time, hr %#x.\n", hr);
1803 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1804 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
1805 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
1807 hr = IMFPresentationClock_Start(clock, 0);
1808 ok(hr == S_OK, "Failed to start the clock, hr %#x.\n", hr);
1810 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1811 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
1812 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
1814 hr = IMFShutdown_Shutdown(shutdown);
1815 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1817 IMFShutdown_Release(shutdown);
1819 IMFPresentationClock_Release(clock);
1821 hr = MFShutdown();
1822 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1825 static HRESULT WINAPI grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, void **obj)
1827 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
1828 IsEqualIID(riid, &IID_IMFClockStateSink) ||
1829 IsEqualIID(riid, &IID_IUnknown))
1831 *obj = iface;
1832 IMFSampleGrabberSinkCallback_AddRef(iface);
1833 return S_OK;
1836 *obj = NULL;
1837 return E_NOINTERFACE;
1840 static ULONG WINAPI grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
1842 return 2;
1845 static ULONG WINAPI grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
1847 return 1;
1850 static HRESULT WINAPI grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset)
1852 return E_NOTIMPL;
1855 static HRESULT WINAPI grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME time)
1857 return E_NOTIMPL;
1860 static HRESULT WINAPI grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME time)
1862 return E_NOTIMPL;
1865 static HRESULT WINAPI grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME time)
1867 return E_NOTIMPL;
1870 static HRESULT WINAPI grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME time, float rate)
1872 return E_NOTIMPL;
1875 static HRESULT WINAPI grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
1876 IMFPresentationClock *clock)
1878 return S_OK;
1881 static HRESULT WINAPI grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
1882 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
1884 return E_NOTIMPL;
1887 static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
1889 return S_OK;
1892 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
1894 grabber_callback_QueryInterface,
1895 grabber_callback_AddRef,
1896 grabber_callback_Release,
1897 grabber_callback_OnClockStart,
1898 grabber_callback_OnClockStop,
1899 grabber_callback_OnClockPause,
1900 grabber_callback_OnClockRestart,
1901 grabber_callback_OnClockSetRate,
1902 grabber_callback_OnSetPresentationClock,
1903 grabber_callback_OnProcessSample,
1904 grabber_callback_OnShutdown,
1907 static IMFSampleGrabberSinkCallback grabber_callback = { &grabber_callback_vtbl };
1909 static void test_sample_grabber(void)
1911 IMFMediaType *media_type, *media_type2, *media_type3;
1912 IMFMediaTypeHandler *handler, *handler2;
1913 IMFPresentationTimeSource *time_source;
1914 IMFPresentationClock *clock, *clock2;
1915 IMFStreamSink *stream, *stream2;
1916 IMFClockStateSink *clocksink;
1917 IMFMediaEventGenerator *eg;
1918 IMFMediaSink *sink, *sink2;
1919 DWORD flags, count, id;
1920 IMFActivate *activate;
1921 IMFMediaEvent *event;
1922 ULONG refcount;
1923 IUnknown *unk;
1924 HRESULT hr;
1925 GUID guid;
1927 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1928 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1930 hr = MFCreateMediaType(&media_type);
1931 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1933 hr = MFCreateSampleGrabberSinkActivate(NULL, NULL, &activate);
1934 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1936 hr = MFCreateSampleGrabberSinkActivate(NULL, &grabber_callback, &activate);
1937 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1939 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
1940 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
1942 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1943 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1944 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
1945 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1947 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
1948 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
1950 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
1951 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
1952 ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags);
1954 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
1955 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
1956 ok(count == 1, "Unexpected stream count %u.\n", count);
1958 EXPECT_REF(sink, 3);
1959 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream);
1960 ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
1961 EXPECT_REF(sink, 3);
1962 EXPECT_REF(stream, 2);
1964 hr = IMFStreamSink_GetIdentifier(stream, &id);
1965 ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr);
1966 ok(id == 0, "Unexpected id %#x.\n", id);
1968 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
1969 ok(hr == S_OK, "Failed to get media sink, hr %x.\n", hr);
1970 ok(sink2 == sink, "Unexpected sink.\n");
1971 IMFMediaSink_Release(sink2);
1973 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 1, &stream2);
1974 ok(hr == MF_E_INVALIDINDEX, "Unexpected hr %#x.\n", hr);
1976 hr = IMFMediaSink_GetStreamSinkById(sink, 1, &stream2);
1977 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
1979 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
1980 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
1982 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
1983 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
1985 hr = IMFMediaSink_RemoveStreamSink(sink, 1);
1986 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
1988 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&clocksink);
1989 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
1990 IMFClockStateSink_Release(clocksink);
1992 /* Event generator. */
1993 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaEventGenerator, (void **)&eg);
1994 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
1996 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
1997 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
1999 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&unk);
2000 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2002 hr = IMFStreamSink_QueryInterface(stream, &IID_IMFMediaTypeHandler, (void **)&handler2);
2003 ok(hr == S_OK, "Failed to get handler interface, hr %#x.\n", hr);
2005 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2006 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2007 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2008 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2009 ok(count == 0, "Unexpected count %u.\n", count);
2010 ok(handler == handler2, "Unexpected handler.\n");
2012 IMFMediaTypeHandler_Release(handler);
2013 IMFMediaTypeHandler_Release(handler2);
2015 /* Set clock. */
2016 hr = MFCreatePresentationClock(&clock);
2017 ok(hr == S_OK, "Failed to create clock object, hr %#x.\n", hr);
2019 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
2020 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2022 hr = IMFMediaSink_GetPresentationClock(sink, &clock2);
2023 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
2025 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
2026 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2028 hr = IMFMediaSink_SetPresentationClock(sink, clock);
2029 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2031 hr = MFCreateSystemTimeSource(&time_source);
2032 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2034 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
2035 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
2036 IMFPresentationTimeSource_Release(time_source);
2038 IMFPresentationClock_Release(clock);
2040 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2041 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2043 hr = IMFActivate_ShutdownObject(activate);
2044 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2046 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2047 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2049 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2050 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2052 /* On Win8+ this initialization happens automatically. */
2053 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
2054 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
2056 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
2057 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2059 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2060 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2061 ok(count == 0, "Unexpected count %u.\n", count);
2063 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2064 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2065 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
2067 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
2068 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2069 ok(media_type2 == media_type, "Unexpected media type.\n");
2070 IMFMediaType_Release(media_type2);
2072 hr = MFCreateMediaType(&media_type2);
2073 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2075 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2076 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2077 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2078 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2080 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2081 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2082 IMFMediaType_Release(media_type);
2084 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
2085 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2087 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
2088 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2089 ok(media_type2 == media_type, "Unexpected media type.\n");
2090 IMFMediaType_Release(media_type);
2092 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
2093 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2095 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, NULL);
2096 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2098 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
2099 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2101 hr = MFCreateMediaType(&media_type);
2102 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2104 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2105 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2107 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
2108 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2110 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2111 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2113 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2114 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2116 media_type3 = (void *)0xdeadbeef;
2117 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2118 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2119 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2121 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1);
2122 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2124 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 1024);
2125 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2127 media_type3 = (void *)0xdeadbeef;
2128 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2129 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2130 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2132 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2133 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2135 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2136 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2138 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
2139 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2141 hr = IMFMediaSink_Shutdown(sink);
2142 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2144 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2145 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2147 hr = IMFMediaSink_Shutdown(sink);
2148 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2150 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2151 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2153 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
2154 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2156 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2157 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2159 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream2);
2160 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2162 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
2163 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2165 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
2166 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2168 id = 1;
2169 hr = IMFStreamSink_GetIdentifier(stream, &id);
2170 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2171 ok(id == 1, "Unexpected id %u.\n", id);
2173 media_type3 = (void *)0xdeadbeef;
2174 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
2175 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2176 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
2178 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2179 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2181 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2182 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
2184 IMFMediaType_Release(media_type2);
2185 IMFMediaType_Release(media_type);
2187 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
2188 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2190 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
2191 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2193 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
2194 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2196 hr = IMFMediaTypeHandler_GetMajorType(handler, NULL);
2197 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2199 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2200 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2202 IMFMediaTypeHandler_Release(handler);
2204 handler = (void *)0xdeadbeef;
2205 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2206 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
2207 ok(handler == (void *)0xdeadbeef, "Unexpected pointer.\n");
2209 hr = IMFStreamSink_GetMediaTypeHandler(stream, NULL);
2210 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2212 IMFMediaEventGenerator_Release(eg);
2213 IMFMediaSink_Release(sink);
2214 IMFStreamSink_Release(stream);
2216 refcount = IMFActivate_Release(activate);
2217 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2219 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
2220 hr = MFCreateMediaType(&media_type);
2221 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2223 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2224 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2225 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2226 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2228 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2229 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2231 hr = IMFActivate_SetUINT32(activate, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 1);
2232 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2234 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2235 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2237 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2238 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2239 ok(flags & MEDIASINK_RATELESS, "Unexpected flags %#x.\n", flags);
2241 hr = IMFActivate_ShutdownObject(activate);
2242 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2244 hr = IMFMediaSink_Shutdown(sink);
2245 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2247 IMFMediaSink_Release(sink);
2249 /* Detaching */
2250 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2251 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2253 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2254 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2255 IMFMediaSink_Release(sink);
2257 hr = IMFActivate_ShutdownObject(activate);
2258 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2260 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2261 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2263 hr = IMFActivate_GetCount(activate, &count);
2264 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2266 hr = IMFActivate_DetachObject(activate);
2267 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2269 IMFActivate_Release(activate);
2271 IMFMediaType_Release(media_type);
2273 hr = MFShutdown();
2274 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2277 static BOOL is_supported_video_type(const GUID *guid)
2279 return IsEqualGUID(guid, &MFVideoFormat_L8)
2280 || IsEqualGUID(guid, &MFVideoFormat_L16)
2281 || IsEqualGUID(guid, &MFVideoFormat_D16)
2282 || IsEqualGUID(guid, &MFVideoFormat_IYUV)
2283 || IsEqualGUID(guid, &MFVideoFormat_YV12)
2284 || IsEqualGUID(guid, &MFVideoFormat_NV12)
2285 || IsEqualGUID(guid, &MFVideoFormat_420O)
2286 || IsEqualGUID(guid, &MFVideoFormat_P010)
2287 || IsEqualGUID(guid, &MFVideoFormat_P016)
2288 || IsEqualGUID(guid, &MFVideoFormat_UYVY)
2289 || IsEqualGUID(guid, &MFVideoFormat_YUY2)
2290 || IsEqualGUID(guid, &MFVideoFormat_P208)
2291 || IsEqualGUID(guid, &MFVideoFormat_NV11)
2292 || IsEqualGUID(guid, &MFVideoFormat_AYUV)
2293 || IsEqualGUID(guid, &MFVideoFormat_ARGB32)
2294 || IsEqualGUID(guid, &MFVideoFormat_RGB32)
2295 || IsEqualGUID(guid, &MFVideoFormat_A2R10G10B10)
2296 || IsEqualGUID(guid, &MFVideoFormat_A16B16G16R16F)
2297 || IsEqualGUID(guid, &MFVideoFormat_RGB24)
2298 || IsEqualGUID(guid, &MFVideoFormat_I420)
2299 || IsEqualGUID(guid, &MFVideoFormat_YVYU)
2300 || IsEqualGUID(guid, &MFVideoFormat_RGB555)
2301 || IsEqualGUID(guid, &MFVideoFormat_RGB565)
2302 || IsEqualGUID(guid, &MFVideoFormat_RGB8)
2303 || IsEqualGUID(guid, &MFVideoFormat_Y216)
2304 || IsEqualGUID(guid, &MFVideoFormat_v410)
2305 || IsEqualGUID(guid, &MFVideoFormat_Y41P)
2306 || IsEqualGUID(guid, &MFVideoFormat_Y41T)
2307 || IsEqualGUID(guid, &MFVideoFormat_Y42T)
2308 || IsEqualGUID(guid, &MFVideoFormat_ABGR32);
2311 static void test_video_processor(void)
2313 DWORD input_count, output_count, input_id, output_id, flags;
2314 DWORD input_min, input_max, output_min, output_max, i, count;
2315 IMFAttributes *attributes, *attributes2;
2316 IMFMediaType *media_type, *media_type2;
2317 MFT_OUTPUT_DATA_BUFFER output_buffer;
2318 MFT_OUTPUT_STREAM_INFO output_info;
2319 MFT_INPUT_STREAM_INFO input_info;
2320 IMFSample *sample, *sample2;
2321 IMFTransform *transform;
2322 IMFMediaBuffer *buffer;
2323 IMFMediaEvent *event;
2324 IUnknown *unk;
2325 HRESULT hr;
2326 GUID guid;
2328 hr = CoInitialize(NULL);
2329 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2331 hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
2332 (void **)&transform);
2333 if (FAILED(hr))
2335 skip("Failed to create Video Processor instance, skipping tests.\n");
2336 goto failed;
2339 hr = IMFTransform_QueryInterface(transform, &IID_IMFMediaEventGenerator, (void **)&unk);
2340 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2342 hr = IMFTransform_QueryInterface(transform, &IID_IMFShutdown, (void **)&unk);
2343 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2345 /* Transform global attributes. */
2346 hr = IMFTransform_GetAttributes(transform, &attributes);
2347 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
2348 hr = IMFTransform_GetAttributes(transform, &attributes2);
2349 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
2350 ok(attributes == attributes2, "Unexpected instance.\n");
2351 IMFAttributes_Release(attributes);
2352 IMFAttributes_Release(attributes2);
2354 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
2355 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
2356 ok(input_min == input_max && input_min == 1 && output_min == output_max && output_min == 1,
2357 "Unexpected stream limits.\n");
2359 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
2360 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
2361 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u, %u.\n", input_count, output_count);
2363 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
2364 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2366 input_id = 100;
2367 hr = IMFTransform_AddInputStreams(transform, 1, &input_id);
2368 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2370 hr = IMFTransform_DeleteInputStream(transform, 0);
2371 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2373 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
2374 todo_wine
2375 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2377 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
2378 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2380 hr = IMFTransform_GetOutputStatus(transform, &flags);
2381 todo_wine
2382 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2384 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
2385 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
2386 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes2);
2387 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
2388 ok(attributes == attributes2, "Unexpected instance.\n");
2389 IMFAttributes_Release(attributes);
2390 IMFAttributes_Release(attributes2);
2392 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
2393 todo_wine
2394 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2396 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
2397 todo_wine
2398 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2400 hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type);
2401 todo_wine
2402 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2404 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
2405 todo_wine
2406 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2408 hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type);
2409 todo_wine
2410 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2412 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
2413 todo_wine
2414 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2416 memset(&input_info, 0xcc, sizeof(input_info));
2417 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
2418 todo_wine {
2419 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2420 ok(input_info.dwFlags == 0, "Unexpected flag %#x.\n", input_info.dwFlags);
2421 ok(input_info.cbSize == 0, "Unexpected size %u.\n", input_info.cbSize);
2422 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
2423 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
2425 hr = MFCreateMediaEvent(MEUnknown, &GUID_NULL, S_OK, NULL, &event);
2426 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2427 hr = IMFTransform_ProcessEvent(transform, 0, event);
2428 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2429 hr = IMFTransform_ProcessEvent(transform, 1, event);
2430 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2431 IMFMediaEvent_Release(event);
2433 /* Configure stream types. */
2434 for (i = 0;;++i)
2436 if (FAILED(hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type)))
2438 todo_wine
2439 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2440 break;
2443 hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type2);
2444 ok(hr == S_OK, "Failed to get available type, hr %#x.\n", hr);
2445 ok(media_type != media_type2, "Unexpected instance.\n");
2446 IMFMediaType_Release(media_type2);
2448 hr = IMFMediaType_GetMajorType(media_type, &guid);
2449 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2450 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
2452 hr = IMFMediaType_GetCount(media_type, &count);
2453 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
2454 ok(count == 2, "Unexpected count %u.\n", count);
2456 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
2457 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
2458 ok(is_supported_video_type(&guid), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid));
2460 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
2461 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2463 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2464 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2466 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
2467 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
2469 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
2470 if (IsEqualGUID(&guid, &MFVideoFormat_L8) || IsEqualGUID(&guid, &MFVideoFormat_L16)
2471 || IsEqualGUID(&guid, &MFVideoFormat_D16) || IsEqualGUID(&guid, &MFVideoFormat_420O)
2472 || IsEqualGUID(&guid, &MFVideoFormat_A16B16G16R16F))
2474 IMFMediaType_Release(media_type);
2475 continue;
2478 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
2479 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2481 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
2482 ok(hr == S_OK, "Failed to test input type %s, hr %#x.\n", wine_dbgstr_guid(&guid), hr);
2484 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2485 ok(hr == S_OK, "Failed to test input type, hr %#x.\n", hr);
2487 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
2488 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2489 ok(media_type != media_type2, "Unexpected instance.\n");
2490 IMFMediaType_Release(media_type2);
2492 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
2493 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
2494 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected input status %#x.\n", flags);
2496 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
2497 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2498 ok(input_info.dwFlags == 0, "Unexpected flags %#x.\n", input_info.dwFlags);
2499 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
2500 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
2502 IMFMediaType_Release(media_type);
2505 /* IYUV -> RGB32 */
2506 hr = MFCreateMediaType(&media_type);
2507 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2509 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
2510 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2512 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_IYUV);
2513 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2515 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
2516 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2518 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
2519 todo_wine
2520 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
2522 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
2523 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2525 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
2526 todo_wine
2527 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
2529 memset(&output_info, 0, sizeof(output_info));
2530 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
2531 todo_wine
2532 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
2533 ok(output_info.dwFlags == 0, "Unexpected flags %#x.\n", output_info.dwFlags);
2534 todo_wine
2535 ok(output_info.cbSize > 0, "Unexpected size %u.\n", output_info.cbSize);
2536 ok(output_info.cbAlignment == 0, "Unexpected alignment %u.\n", output_info.cbAlignment);
2538 hr = MFCreateSample(&sample);
2539 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2541 hr = MFCreateSample(&sample2);
2542 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2544 memset(&output_buffer, 0, sizeof(output_buffer));
2545 output_buffer.pSample = sample;
2546 flags = 0;
2547 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2548 todo_wine
2549 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2550 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2551 ok(flags == 0, "Unexpected status %#x.\n", flags);
2553 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
2554 todo_wine
2555 ok(hr == S_OK, "Failed to push a sample, hr %#x.\n", hr);
2557 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
2558 todo_wine
2559 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
2561 memset(&output_buffer, 0, sizeof(output_buffer));
2562 output_buffer.pSample = sample;
2563 flags = 0;
2564 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2565 todo_wine
2566 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2567 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2568 ok(flags == 0, "Unexpected status %#x.\n", flags);
2570 hr = IMFSample_SetSampleTime(sample2, 0);
2571 ok(hr == S_OK, "Failed to set sample time, hr %#x.\n", hr);
2572 memset(&output_buffer, 0, sizeof(output_buffer));
2573 output_buffer.pSample = sample;
2574 flags = 0;
2575 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2576 todo_wine
2577 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2578 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2579 ok(flags == 0, "Unexpected status %#x.\n", flags);
2581 hr = MFCreateMemoryBuffer(1024 * 1024, &buffer);
2582 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2584 hr = IMFSample_AddBuffer(sample2, buffer);
2585 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
2587 hr = IMFSample_AddBuffer(sample, buffer);
2588 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
2590 memset(&output_buffer, 0, sizeof(output_buffer));
2591 output_buffer.pSample = sample;
2592 flags = 0;
2593 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2594 todo_wine
2595 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr);
2596 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2597 ok(flags == 0, "Unexpected status %#x.\n", flags);
2599 if (SUCCEEDED(hr))
2601 memset(&output_buffer, 0, sizeof(output_buffer));
2602 output_buffer.pSample = sample;
2603 flags = 0;
2604 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
2605 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
2606 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
2607 ok(flags == 0, "Unexpected status %#x.\n", flags);
2610 IMFSample_Release(sample2);
2611 IMFSample_Release(sample);
2612 IMFMediaBuffer_Release(buffer);
2614 IMFMediaType_Release(media_type);
2616 IMFTransform_Release(transform);
2618 failed:
2619 CoUninitialize();
2622 static void test_quality_manager(void)
2624 IMFQualityManager *manager;
2625 HRESULT hr;
2627 hr = MFCreateStandardQualityManager(&manager);
2628 ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr);
2630 IMFQualityManager_Release(manager);
2633 static void test_sar(void)
2635 IMFPresentationClock *present_clock, *present_clock2;
2636 IMFPresentationTimeSource *time_source;
2637 IMFClockStateSink *state_sink;
2638 IMFMediaSink *sink, *sink2;
2639 IMFStreamSink *stream_sink;
2640 IMFAttributes *attributes;
2641 IMFActivate *activate;
2642 MFCLOCK_STATE state;
2643 DWORD flags, count;
2644 IMFClock *clock;
2645 IUnknown *unk;
2646 HRESULT hr;
2648 hr = CoInitialize(NULL);
2649 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2651 hr = MFCreateAudioRenderer(NULL, &sink);
2652 if (hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE)
2654 skip("No audio playback device available.\n");
2655 CoUninitialize();
2656 return;
2658 ok(hr == S_OK, "Failed to create renderer, hr %#x.\n", hr);
2660 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2661 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
2663 hr = MFCreatePresentationClock(&present_clock);
2664 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
2666 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&time_source);
2667 todo_wine
2668 ok(hr == S_OK, "Failed to get time source interface, hr %#x.\n", hr);
2670 if (SUCCEEDED(hr))
2672 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
2673 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
2675 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &flags);
2676 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
2677 ok(flags == MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ, "Unexpected flags %#x.\n", flags);
2679 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2680 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2681 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
2683 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&state_sink);
2684 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
2686 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
2687 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
2689 IMFClockStateSink_Release(state_sink);
2691 IMFPresentationTimeSource_Release(time_source);
2693 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
2694 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2696 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
2697 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2699 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
2700 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2702 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2703 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2704 ok(count == 1, "Unexpected count %u.\n", count);
2706 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2707 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2708 ok(flags == (MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL), "Unexpected flags %#x.\n", flags);
2710 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaSinkPreroll, (void **)&unk);
2711 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
2712 IUnknown_Release(unk);
2714 /* Events */
2715 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaEventGenerator, (void **)&unk);
2716 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
2717 IUnknown_Release(unk);
2719 /* Clock */
2720 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&unk);
2721 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
2722 IUnknown_Release(unk);
2724 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
2725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2727 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
2728 todo_wine
2729 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2731 hr = MFCreateSystemTimeSource(&time_source);
2732 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2734 hr = IMFPresentationClock_SetTimeSource(present_clock, time_source);
2735 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
2736 IMFPresentationTimeSource_Release(time_source);
2738 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
2739 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2741 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
2742 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2744 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
2745 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2746 ok(present_clock == present_clock2, "Unexpected instance.\n");
2747 IMFPresentationClock_Release(present_clock2);
2749 /* Shutdown */
2750 hr = IMFMediaSink_Shutdown(sink);
2751 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2753 hr = IMFMediaSink_Shutdown(sink);
2754 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2756 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
2757 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2759 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
2760 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2762 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
2763 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2765 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2766 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2768 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2769 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2771 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
2772 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2774 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
2775 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2777 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
2778 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2780 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
2781 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2783 IMFMediaSink_Release(sink);
2785 /* Activation */
2786 hr = MFCreateAudioRendererActivate(&activate);
2787 ok(hr == S_OK, "Failed to create activation object, hr %#x.\n", hr);
2789 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2790 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2792 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
2793 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2794 ok(sink == sink2, "Unexpected instance.\n");
2795 IMFMediaSink_Release(sink2);
2797 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2798 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2800 hr = IMFActivate_ShutdownObject(activate);
2801 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2803 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2804 todo_wine
2805 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2807 IMFMediaSink_Release(sink);
2809 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2810 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2812 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2813 todo_wine
2814 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2816 IMFMediaSink_Release(sink);
2818 hr = IMFActivate_DetachObject(activate);
2819 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2821 IMFActivate_Release(activate);
2823 IMFPresentationClock_Release(present_clock);
2825 hr = MFShutdown();
2826 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
2828 /* SAR attributes */
2829 hr = MFCreateAttributes(&attributes, 0);
2830 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
2832 /* Specify role. */
2833 hr = IMFAttributes_SetUINT32(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia);
2834 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2836 hr = MFCreateAudioRenderer(attributes, &sink);
2837 ok(hr == S_OK, "Failed to create a sink, hr %#x.\n", hr);
2838 IMFMediaSink_Release(sink);
2840 /* Invalid endpoint. */
2841 hr = IMFAttributes_SetString(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, L"endpoint");
2842 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2844 hr = MFCreateAudioRenderer(attributes, &sink);
2845 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2847 hr = IMFAttributes_DeleteItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE);
2848 ok(hr == S_OK, "Failed to remove attribute, hr %#x.\n", hr);
2850 hr = MFCreateAudioRenderer(attributes, &sink);
2851 ok(hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE, "Failed to create a sink, hr %#x.\n", hr);
2853 CoUninitialize();
2856 static void test_evr(void)
2858 IMFMediaSink *sink, *sink2;
2859 IMFActivate *activate;
2860 DWORD flags;
2861 HRESULT hr;
2863 hr = CoInitialize(NULL);
2864 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2866 hr = MFCreateVideoRendererActivate(NULL, NULL);
2867 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2869 hr = MFCreateVideoRendererActivate(NULL, &activate);
2870 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
2872 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2873 todo_wine
2874 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2876 if (hr == S_OK)
2878 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2881 hr = IMFActivate_ShutdownObject(activate);
2882 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2884 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2885 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2887 /* Activate again. */
2888 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
2889 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2890 ok(sink == sink2, "Unexpected instance.\n");
2891 IMFMediaSink_Release(sink2);
2893 hr = IMFActivate_DetachObject(activate);
2894 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
2896 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2897 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2899 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
2900 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
2902 hr = IMFActivate_ShutdownObject(activate);
2903 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2905 IMFMediaSink_Release(sink2);
2906 IMFMediaSink_Release(sink);
2908 IMFActivate_Release(activate);
2910 CoUninitialize();
2913 static void test_MFCreateSimpleTypeHandler(void)
2915 IMFMediaType *media_type, *media_type2, *media_type3;
2916 IMFMediaTypeHandler *handler;
2917 DWORD count;
2918 HRESULT hr;
2919 GUID guid;
2921 hr = MFCreateSimpleTypeHandler(&handler);
2922 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2924 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
2925 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2927 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2928 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2930 count = 0;
2931 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2932 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
2933 ok(count == 1, "Unexpected count %u.\n", count);
2935 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
2936 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2938 media_type = (void *)0xdeadbeef;
2939 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
2940 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2941 ok(!media_type, "Unexpected pointer.\n");
2943 hr = MFCreateMediaType(&media_type);
2944 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2946 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
2947 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2949 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
2950 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
2952 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type2);
2953 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2954 ok(media_type2 == media_type, "Unexpected type.\n");
2955 IMFMediaType_Release(media_type2);
2957 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
2958 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2960 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
2961 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2963 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type2);
2964 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2966 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 1, &media_type2);
2967 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2969 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
2970 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2971 ok(media_type == media_type2, "Unexpected pointer.\n");
2972 IMFMediaType_Release(media_type2);
2974 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2975 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
2977 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
2978 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2980 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2981 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2982 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
2984 hr = MFCreateMediaType(&media_type3);
2985 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2987 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, NULL);
2988 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2990 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2991 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2993 /* Different major types. */
2994 media_type2 = (void *)0xdeadbeef;
2995 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
2996 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
2997 ok(!media_type2, "Unexpected pointer.\n");
2999 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3000 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3002 media_type2 = (void *)0xdeadbeef;
3003 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3004 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3005 ok(!media_type2, "Unexpected pointer.\n");
3007 /* Handler missing subtype. */
3008 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3009 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3011 media_type2 = (void *)0xdeadbeef;
3012 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3013 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3014 ok(!media_type2, "Unexpected pointer.\n");
3016 /* Different subtypes. */
3017 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
3018 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3020 media_type2 = (void *)0xdeadbeef;
3021 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3022 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3023 ok(!media_type2, "Unexpected pointer.\n");
3025 /* Same major/subtype. */
3026 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
3027 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3029 media_type2 = (void *)0xdeadbeef;
3030 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3032 ok(!media_type2, "Unexpected pointer.\n");
3034 /* Set one more attribute. */
3035 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)4 << 32 | 4);
3036 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3038 media_type2 = (void *)0xdeadbeef;
3039 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
3040 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3041 ok(!media_type2, "Unexpected pointer.\n");
3043 IMFMediaType_Release(media_type3);
3044 IMFMediaType_Release(media_type);
3046 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3047 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3049 media_type = (void *)0xdeadbeef;
3050 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
3051 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3052 ok(!media_type, "Unexpected pointer.\n");
3054 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3055 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3057 IMFMediaTypeHandler_Release(handler);
3060 static void test_MFGetSupportedMimeTypes(void)
3062 PROPVARIANT value;
3063 HRESULT hr;
3065 hr = MFGetSupportedMimeTypes(NULL);
3066 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3068 value.vt = VT_EMPTY;
3069 hr = MFGetSupportedMimeTypes(&value);
3070 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3071 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
3073 PropVariantClear(&value);
3076 static void test_MFGetSupportedSchemes(void)
3078 PROPVARIANT value;
3079 HRESULT hr;
3081 hr = MFGetSupportedSchemes(NULL);
3082 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3084 value.vt = VT_EMPTY;
3085 hr = MFGetSupportedSchemes(&value);
3086 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3087 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
3089 PropVariantClear(&value);
3092 static BOOL is_sample_copier_available_type(IMFMediaType *type)
3094 GUID major = { 0 };
3095 UINT32 count;
3096 HRESULT hr;
3098 hr = IMFMediaType_GetMajorType(type, &major);
3099 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3101 hr = IMFMediaType_GetCount(type, &count);
3102 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3103 ok(count == 1, "Unexpected attribute count %u.\n", count);
3105 return IsEqualGUID(&major, &MFMediaType_Video) || IsEqualGUID(&major, &MFMediaType_Audio);
3108 static void test_sample_copier(void)
3110 DWORD in_min, in_max, out_min, out_max;
3111 IMFMediaType *mediatype, *mediatype2;
3112 MFT_OUTPUT_STREAM_INFO output_info;
3113 IMFSample *sample, *client_sample;
3114 MFT_INPUT_STREAM_INFO input_info;
3115 DWORD input_count, output_count;
3116 MFT_OUTPUT_DATA_BUFFER buffer;
3117 IMFMediaBuffer *media_buffer;
3118 IMFAttributes *attributes;
3119 IMFTransform *copier;
3120 DWORD flags, status;
3121 HRESULT hr;
3123 hr = MFCreateSampleCopierMFT(&copier);
3124 ok(hr == S_OK, "Failed to create sample copier, hr %#x.\n", hr);
3126 hr = IMFTransform_GetAttributes(copier, &attributes);
3127 ok(hr == S_OK, "Failed to get transform attributes, hr %#x.\n", hr);
3128 IMFAttributes_Release(attributes);
3130 hr = IMFTransform_GetInputStreamAttributes(copier, 0, &attributes);
3131 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3133 hr = IMFTransform_GetInputStreamAttributes(copier, 1, &attributes);
3134 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3136 hr = IMFTransform_GetOutputStreamAttributes(copier, 0, &attributes);
3137 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3139 hr = IMFTransform_GetOutputStreamAttributes(copier, 1, &attributes);
3140 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3142 hr = IMFTransform_SetOutputBounds(copier, 0, 0);
3143 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3145 /* No dynamic streams. */
3146 input_count = output_count = 0;
3147 hr = IMFTransform_GetStreamCount(copier, &input_count, &output_count);
3148 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
3149 ok(input_count == 1 && output_count == 1, "Unexpected streams count.\n");
3151 hr = IMFTransform_GetStreamLimits(copier, &in_min, &in_max, &out_min, &out_max);
3152 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
3153 ok(in_min == in_max && in_min == 1 && out_min == out_max && out_min == 1, "Unexpected stream limits.\n");
3155 hr = IMFTransform_GetStreamIDs(copier, 1, &input_count, 1, &output_count);
3156 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3158 hr = IMFTransform_DeleteInputStream(copier, 0);
3159 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3161 /* Available types. */
3162 hr = IMFTransform_GetInputAvailableType(copier, 0, 0, &mediatype);
3163 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3164 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
3165 IMFMediaType_Release(mediatype);
3167 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype);
3168 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3169 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
3170 IMFMediaType_Release(mediatype);
3172 hr = IMFTransform_GetInputAvailableType(copier, 0, 2, &mediatype);
3173 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3175 hr = IMFTransform_GetInputAvailableType(copier, 1, 0, &mediatype);
3176 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3178 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype);
3179 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3181 hr = IMFTransform_GetOutputAvailableType(copier, 1, 0, &mediatype);
3182 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3184 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype);
3185 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3187 hr = IMFTransform_GetInputCurrentType(copier, 1, &mediatype);
3188 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3190 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype);
3191 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3193 hr = IMFTransform_GetOutputCurrentType(copier, 1, &mediatype);
3194 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3196 hr = MFCreateSample(&sample);
3197 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
3199 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
3200 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3202 hr = MFCreateMediaType(&mediatype);
3203 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3205 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3206 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3208 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3209 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3211 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3212 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3214 hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16);
3215 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3217 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
3218 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3219 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
3220 ok(!output_info.cbSize, "Unexpected size %u.\n", output_info.cbSize);
3221 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
3223 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
3224 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3226 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
3227 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
3228 ok(!input_info.cbSize, "Unexpected size %u.\n", input_info.cbSize);
3229 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
3230 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
3232 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3233 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
3235 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
3236 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3237 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
3238 ok(output_info.cbSize == 16 * 16, "Unexpected size %u.\n", output_info.cbSize);
3239 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
3241 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3242 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3243 IMFMediaType_Release(mediatype2);
3245 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
3246 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3248 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
3249 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3251 /* Setting input type resets output type. */
3252 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3253 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3254 IMFMediaType_Release(mediatype2);
3256 hr = IMFTransform_SetInputType(copier, 0, mediatype, 0);
3257 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
3259 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
3260 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3262 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype2);
3263 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3264 ok(is_sample_copier_available_type(mediatype2), "Unexpected type.\n");
3265 IMFMediaType_Release(mediatype2);
3267 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
3268 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3269 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
3270 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
3271 ok(input_info.cbSize == 16 * 16, "Unexpected size %u.\n", input_info.cbSize);
3272 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
3273 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
3275 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype2);
3276 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3277 hr = IMFMediaType_IsEqual(mediatype2, mediatype, &flags);
3278 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3279 IMFMediaType_Release(mediatype2);
3281 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
3282 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
3283 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected flags %#x.\n", flags);
3285 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
3286 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3287 IMFMediaType_Release(mediatype2);
3289 hr = IMFTransform_GetOutputStatus(copier, &flags);
3290 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3292 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
3293 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
3295 hr = IMFTransform_GetOutputStatus(copier, &flags);
3296 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
3297 ok(!flags, "Unexpected flags %#x.\n", flags);
3299 /* Pushing samples. */
3300 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
3301 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
3303 hr = IMFSample_AddBuffer(sample, media_buffer);
3304 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
3305 IMFMediaBuffer_Release(media_buffer);
3307 EXPECT_REF(sample, 1);
3308 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
3309 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
3310 EXPECT_REF(sample, 2);
3312 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
3313 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
3314 ok(!flags, "Unexpected flags %#x.\n", flags);
3316 hr = IMFTransform_GetOutputStatus(copier, &flags);
3317 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
3318 ok(flags == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected flags %#x.\n", flags);
3320 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
3321 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
3323 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
3324 ok(hr == S_OK, "Failed to get output info, hr %#x.\n", hr);
3326 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
3327 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
3329 hr = MFCreateSample(&client_sample);
3330 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
3332 hr = IMFSample_AddBuffer(client_sample, media_buffer);
3333 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
3334 IMFMediaBuffer_Release(media_buffer);
3336 status = 0;
3337 memset(&buffer, 0, sizeof(buffer));
3338 buffer.pSample = client_sample;
3339 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
3340 ok(hr == S_OK, "Failed to get output, hr %#x.\n", hr);
3341 EXPECT_REF(sample, 1);
3343 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
3344 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Failed to get output, hr %#x.\n", hr);
3346 /* Flushing. */
3347 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
3348 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
3349 EXPECT_REF(sample, 2);
3351 hr = IMFTransform_ProcessMessage(copier, MFT_MESSAGE_COMMAND_FLUSH, 0);
3352 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
3353 EXPECT_REF(sample, 1);
3355 IMFSample_Release(sample);
3356 IMFSample_Release(client_sample);
3358 IMFMediaType_Release(mediatype);
3359 IMFTransform_Release(copier);
3362 static void test_MFGetTopoNodeCurrentType(void)
3364 IMFMediaType *media_type, *media_type2;
3365 IMFTopologyNode *node;
3366 HRESULT hr;
3368 /* Tee node. */
3369 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
3370 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
3372 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
3373 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3375 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3376 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3378 hr = MFCreateMediaType(&media_type2);
3379 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3381 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3382 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3384 /* Input type returned, if set. */
3385 hr = IMFTopologyNode_SetInputPrefType(node, 0, media_type2);
3386 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3388 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3389 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3390 ok(media_type == media_type2, "Unexpected pointer.\n");
3391 IMFMediaType_Release(media_type);
3393 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
3394 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3396 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3397 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3399 /* Set second output. */
3400 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
3401 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3403 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3404 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3406 hr = IMFTopologyNode_SetOutputPrefType(node, 1, NULL);
3407 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3409 /* Set first output. */
3410 hr = IMFTopologyNode_SetOutputPrefType(node, 0, media_type2);
3411 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3413 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3414 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3415 ok(media_type == media_type2, "Unexpected pointer.\n");
3416 IMFMediaType_Release(media_type);
3418 hr = IMFTopologyNode_SetOutputPrefType(node, 0, NULL);
3419 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3421 /* Set primary output. */
3422 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
3423 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3425 hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_PRIMARYOUTPUT, 1);
3426 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3428 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
3429 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3430 ok(media_type == media_type2, "Unexpected pointer.\n");
3431 IMFMediaType_Release(media_type);
3433 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
3434 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3435 ok(media_type == media_type2, "Unexpected pointer.\n");
3436 IMFMediaType_Release(media_type);
3438 IMFTopologyNode_Release(node);
3439 IMFMediaType_Release(media_type2);
3442 START_TEST(mf)
3444 test_topology();
3445 test_topology_loader();
3446 test_MFGetService();
3447 test_sequencer_source();
3448 test_media_session();
3449 test_MFShutdownObject();
3450 test_presentation_clock();
3451 test_sample_grabber();
3452 test_video_processor();
3453 test_quality_manager();
3454 test_sar();
3455 test_evr();
3456 test_MFCreateSimpleTypeHandler();
3457 test_MFGetSupportedMimeTypes();
3458 test_MFGetSupportedSchemes();
3459 test_sample_copier();
3460 test_MFGetTopoNodeCurrentType();