mf/topoloader: Set MF_TOPONODE_MEDIASTART for all source nodes.
[wine/zf.git] / dlls / mf / tests / mf.c
blobb2cb45668cb39579ac26d787324d4e1956dc3125
1 /*
2 * Unit tests for mf.dll.
4 * Copyright 2017 Nikolay Sivov
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
23 #include <float.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
30 #include "initguid.h"
31 #include "ole2.h"
33 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
34 DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
35 DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
37 #undef INITGUID
38 #include <guiddef.h>
39 #include "mfapi.h"
40 #include "mferror.h"
41 #include "mfidl.h"
42 #include "initguid.h"
43 #include "uuids.h"
44 #include "mmdeviceapi.h"
45 #include "audioclient.h"
46 #include "evr.h"
48 #include "wine/test.h"
50 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
51 static void _expect_ref(IUnknown* obj, ULONG expected_refcount, int line)
53 ULONG refcount;
54 IUnknown_AddRef(obj);
55 refcount = IUnknown_Release(obj);
56 ok_(__FILE__, line)(refcount == expected_refcount, "Unexpected refcount %d, expected %d.\n", refcount,
57 expected_refcount);
60 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
61 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
63 IUnknown *iface = iface_ptr;
64 HRESULT hr, expected_hr;
65 IUnknown *unk;
67 expected_hr = supported ? S_OK : E_NOINTERFACE;
69 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
70 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
71 if (SUCCEEDED(hr))
72 IUnknown_Release(unk);
75 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
76 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
78 IUnknown *iface = iface_ptr;
79 HRESULT hr, expected_hr;
80 IUnknown *unk;
82 expected_hr = supported ? S_OK : E_NOINTERFACE;
84 hr = MFGetService(iface, service, iid, (void **)&unk);
85 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
86 if (SUCCEEDED(hr))
87 IUnknown_Release(unk);
90 static HWND create_window(void)
92 RECT r = {0, 0, 640, 480};
94 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
96 return CreateWindowA("static", "mf_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
97 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
100 static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
102 if (IsEqualIID(riid, &IID_IUnknown))
104 *obj = iface;
105 IUnknown_AddRef(iface);
106 return S_OK;
109 *obj = NULL;
110 return E_NOINTERFACE;
113 static ULONG WINAPI test_unk_AddRef(IUnknown *iface)
115 return 2;
118 static ULONG WINAPI test_unk_Release(IUnknown *iface)
120 return 1;
123 static const IUnknownVtbl test_unk_vtbl =
125 test_unk_QueryInterface,
126 test_unk_AddRef,
127 test_unk_Release,
130 static void test_topology(void)
132 IMFMediaType *mediatype, *mediatype2, *mediatype3;
133 IMFCollection *collection, *collection2;
134 IUnknown test_unk2 = { &test_unk_vtbl };
135 IUnknown test_unk = { &test_unk_vtbl };
136 IMFTopologyNode *node, *node2, *node3;
137 IMFTopology *topology, *topology2;
138 MF_TOPOLOGY_TYPE node_type;
139 UINT32 count, index;
140 IUnknown *object;
141 WORD node_count;
142 DWORD size;
143 HRESULT hr;
144 TOPOID id;
146 hr = MFCreateTopology(NULL);
147 ok(hr == E_POINTER, "got %#x\n", hr);
149 hr = MFCreateTopology(&topology);
150 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
151 hr = IMFTopology_GetTopologyID(topology, &id);
152 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
153 ok(id == 1, "Unexpected id.\n");
155 hr = MFCreateTopology(&topology2);
156 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
157 hr = IMFTopology_GetTopologyID(topology2, &id);
158 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
159 ok(id == 2, "Unexpected id.\n");
161 IMFTopology_Release(topology);
163 hr = MFCreateTopology(&topology);
164 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
165 hr = IMFTopology_GetTopologyID(topology, &id);
166 ok(hr == S_OK, "Failed to get id, hr %#x.\n", hr);
167 ok(id == 3, "Unexpected id.\n");
169 IMFTopology_Release(topology2);
171 /* No attributes by default. */
172 for (node_type = MF_TOPOLOGY_OUTPUT_NODE; node_type < MF_TOPOLOGY_TEE_NODE; ++node_type)
174 hr = MFCreateTopologyNode(node_type, &node);
175 ok(hr == S_OK, "Failed to create a node for type %d, hr %#x.\n", node_type, hr);
176 hr = IMFTopologyNode_GetCount(node, &count);
177 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
178 ok(!count, "Unexpected attribute count %u.\n", count);
179 IMFTopologyNode_Release(node);
182 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, NULL);
183 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
185 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
186 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
188 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
189 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
191 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
192 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
193 ok(((id >> 32) == GetCurrentProcessId()) && !!(id & 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id));
195 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
196 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
198 hr = IMFTopology_GetNodeCount(topology, NULL);
199 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
201 hr = IMFTopology_AddNode(topology, NULL);
202 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
204 node_count = 1;
205 hr = IMFTopology_GetNodeCount(topology, &node_count);
206 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
207 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
209 /* Same id, different nodes. */
210 hr = IMFTopology_AddNode(topology, node);
211 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
213 node_count = 0;
214 hr = IMFTopology_GetNodeCount(topology, &node_count);
215 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
216 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
218 hr = IMFTopology_AddNode(topology, node2);
219 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
220 IMFTopologyNode_Release(node2);
222 hr = IMFTopology_GetNodeByID(topology, id, &node2);
223 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
224 ok(node2 == node, "Unexpected node.\n");
225 IMFTopologyNode_Release(node2);
227 /* Change node id, add it again. */
228 hr = IMFTopologyNode_SetTopoNodeID(node, ++id);
229 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
231 hr = IMFTopology_GetNodeByID(topology, id, &node2);
232 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
233 ok(node2 == node, "Unexpected node.\n");
234 IMFTopologyNode_Release(node2);
236 hr = IMFTopology_GetNodeByID(topology, id + 1, &node2);
237 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
239 hr = IMFTopology_AddNode(topology, node);
240 ok(hr == E_INVALIDARG, "Failed to add a node, hr %#x.\n", hr);
242 hr = IMFTopology_GetNode(topology, 0, &node2);
243 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
244 ok(node2 == node, "Unexpected node.\n");
245 IMFTopologyNode_Release(node2);
247 hr = IMFTopology_GetNode(topology, 1, NULL);
248 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
250 hr = IMFTopology_GetNode(topology, 1, &node2);
251 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
253 hr = IMFTopology_GetNode(topology, -2, &node2);
254 ok(hr == MF_E_INVALIDINDEX, "Failed to get a node, hr %#x.\n", hr);
256 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
257 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
258 hr = IMFTopology_AddNode(topology, node2);
259 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
260 IMFTopologyNode_Release(node2);
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 == 2, "Unexpected node count %u.\n", node_count);
267 /* Remove with detached node, existing id. */
268 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
269 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
270 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
271 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
272 hr = IMFTopology_RemoveNode(topology, node2);
273 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
274 IMFTopologyNode_Release(node2);
276 hr = IMFTopology_RemoveNode(topology, node);
277 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
279 node_count = 0;
280 hr = IMFTopology_GetNodeCount(topology, &node_count);
281 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
282 ok(node_count == 1, "Unexpected node count %u.\n", node_count);
284 hr = IMFTopology_Clear(topology);
285 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
287 node_count = 1;
288 hr = IMFTopology_GetNodeCount(topology, &node_count);
289 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
290 ok(node_count == 0, "Unexpected node count %u.\n", node_count);
292 hr = IMFTopology_Clear(topology);
293 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
295 hr = IMFTopologyNode_SetTopoNodeID(node, 123);
296 ok(hr == S_OK, "Failed to set node id, hr %#x.\n", hr);
298 IMFTopologyNode_Release(node);
300 /* Change id for attached node. */
301 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
302 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
304 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node2);
305 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
307 hr = IMFTopology_AddNode(topology, node);
308 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
310 hr = IMFTopology_AddNode(topology, node2);
311 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
313 hr = IMFTopologyNode_GetTopoNodeID(node, &id);
314 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
316 hr = IMFTopologyNode_SetTopoNodeID(node2, id);
317 ok(hr == S_OK, "Failed to get node id, hr %#x.\n", hr);
319 hr = IMFTopology_GetNodeByID(topology, id, &node3);
320 ok(hr == S_OK, "Failed to get a node, hr %#x.\n", hr);
321 ok(node3 == node, "Unexpected node.\n");
322 IMFTopologyNode_Release(node3);
324 IMFTopologyNode_Release(node);
325 IMFTopologyNode_Release(node2);
327 /* Source/output collections. */
328 hr = IMFTopology_Clear(topology);
329 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
331 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
332 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
334 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
335 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
336 ok(!!collection, "Unexpected object pointer.\n");
338 hr = IMFTopology_GetSourceNodeCollection(topology, &collection2);
339 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
340 ok(!!collection2, "Unexpected object pointer.\n");
341 ok(collection2 != collection, "Expected cloned collection.\n");
343 hr = IMFCollection_GetElementCount(collection, &size);
344 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
345 ok(!size, "Unexpected item count.\n");
347 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
348 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
350 hr = IMFCollection_GetElementCount(collection, &size);
351 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
352 ok(size == 1, "Unexpected item count.\n");
354 hr = IMFCollection_GetElementCount(collection2, &size);
355 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
356 ok(!size, "Unexpected item count.\n");
358 IMFCollection_Release(collection2);
359 IMFCollection_Release(collection);
361 /* Add some nodes. */
362 hr = IMFTopology_GetSourceNodeCollection(topology, NULL);
363 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
365 hr = IMFTopology_GetOutputNodeCollection(topology, NULL);
366 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
368 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
369 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
370 hr = IMFTopology_AddNode(topology, node);
371 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
372 IMFTopologyNode_Release(node);
374 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
375 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
376 ok(!!collection, "Unexpected object pointer.\n");
377 hr = IMFCollection_GetElementCount(collection, &size);
378 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
379 ok(size == 1, "Unexpected item count.\n");
380 IMFCollection_Release(collection);
382 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
383 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
384 hr = IMFTopology_AddNode(topology, node);
385 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
386 IMFTopologyNode_Release(node);
388 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
389 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
390 ok(!!collection, "Unexpected object pointer.\n");
391 hr = IMFCollection_GetElementCount(collection, &size);
392 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
393 ok(size == 1, "Unexpected item count.\n");
394 IMFCollection_Release(collection);
396 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
397 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
398 hr = IMFTopology_AddNode(topology, node);
399 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
400 IMFTopologyNode_Release(node);
402 hr = IMFTopology_GetSourceNodeCollection(topology, &collection);
403 ok(hr == S_OK, "Failed to get source node collection, hr %#x.\n", hr);
404 ok(!!collection, "Unexpected object pointer.\n");
405 hr = IMFCollection_GetElementCount(collection, &size);
406 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
407 ok(size == 1, "Unexpected item count.\n");
408 IMFCollection_Release(collection);
410 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node);
411 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
412 hr = IMFTopology_AddNode(topology, node);
413 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
415 /* Associated object. */
416 hr = IMFTopologyNode_SetObject(node, NULL);
417 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
419 hr = IMFTopologyNode_GetObject(node, NULL);
420 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
422 object = (void *)0xdeadbeef;
423 hr = IMFTopologyNode_GetObject(node, &object);
424 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
425 ok(!object, "Unexpected object %p.\n", object);
427 hr = IMFTopologyNode_SetObject(node, &test_unk);
428 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
430 hr = IMFTopologyNode_GetObject(node, &object);
431 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
432 ok(object == &test_unk, "Unexpected object %p.\n", object);
433 IUnknown_Release(object);
435 hr = IMFTopologyNode_SetObject(node, &test_unk2);
436 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
438 hr = IMFTopologyNode_GetCount(node, &count);
439 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
440 ok(count == 0, "Unexpected attribute count %u.\n", count);
442 hr = IMFTopologyNode_SetGUID(node, &MF_TOPONODE_TRANSFORM_OBJECTID, &MF_TOPONODE_TRANSFORM_OBJECTID);
443 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
445 hr = IMFTopologyNode_SetObject(node, NULL);
446 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
448 object = (void *)0xdeadbeef;
449 hr = IMFTopologyNode_GetObject(node, &object);
450 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
451 ok(!object, "Unexpected object %p.\n", object);
453 hr = IMFTopologyNode_GetCount(node, &count);
454 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
455 ok(count == 1, "Unexpected attribute count %u.\n", count);
457 /* Preferred stream types. */
458 hr = IMFTopologyNode_GetInputCount(node, &count);
459 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
460 ok(count == 0, "Unexpected count %u.\n", count);
462 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype);
463 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
465 hr = MFCreateMediaType(&mediatype);
466 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
468 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
469 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
471 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
472 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
473 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
474 IMFMediaType_Release(mediatype2);
476 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
477 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
479 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
480 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
481 ok(!mediatype2, "Unexpected mediatype instance.\n");
483 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
484 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
486 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
487 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
489 hr = IMFTopologyNode_GetInputCount(node, &count);
490 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
491 ok(count == 2, "Unexpected count %u.\n", count);
493 hr = IMFTopologyNode_GetOutputCount(node, &count);
494 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
495 ok(count == 0, "Unexpected count %u.\n", count);
497 hr = IMFTopologyNode_SetOutputPrefType(node, 0, mediatype);
498 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
500 IMFTopologyNode_Release(node);
502 /* Source node. */
503 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
504 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
506 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
507 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
509 hr = IMFTopologyNode_SetOutputPrefType(node, 2, mediatype);
510 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
512 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
513 ok(hr == E_FAIL, "Failed to get preferred type, hr %#x.\n", hr);
514 ok(!mediatype2, "Unexpected mediatype instance.\n");
516 hr = IMFTopologyNode_GetOutputCount(node, &count);
517 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
518 ok(count == 3, "Unexpected count %u.\n", count);
520 IMFTopologyNode_Release(node);
522 /* Tee node. */
523 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
524 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
526 hr = IMFTopologyNode_SetInputPrefType(node, 0, mediatype);
527 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
529 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype2);
530 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
531 ok(mediatype2 == mediatype, "Unexpected mediatype instance.\n");
532 IMFMediaType_Release(mediatype2);
534 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
535 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
537 hr = IMFTopologyNode_GetInputCount(node, &count);
538 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
539 ok(count == 0, "Unexpected count %u.\n", count);
541 hr = IMFTopologyNode_SetInputPrefType(node, 1, mediatype);
542 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
544 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
545 ok(hr == MF_E_INVALIDTYPE, "Unexpected 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_GetOutputPrefType(node, 0, &mediatype2);
551 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
553 hr = MFCreateMediaType(&mediatype2);
554 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
556 /* Changing output type does not change input type. */
557 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype2);
558 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
560 hr = IMFTopologyNode_GetInputPrefType(node, 0, &mediatype3);
561 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
562 ok(mediatype3 == mediatype, "Unexpected mediatype instance.\n");
563 IMFMediaType_Release(mediatype3);
565 IMFMediaType_Release(mediatype2);
567 hr = IMFTopologyNode_GetInputCount(node, &count);
568 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
569 ok(count == 0, "Unexpected count %u.\n", count);
571 hr = IMFTopologyNode_GetOutputCount(node, &count);
572 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
573 ok(count == 5, "Unexpected count %u.\n", count);
575 IMFTopologyNode_Release(node);
577 /* Transform node. */
578 hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node);
579 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
581 hr = IMFTopologyNode_SetInputPrefType(node, 3, mediatype);
582 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
584 hr = IMFTopologyNode_GetInputCount(node, &count);
585 ok(hr == S_OK, "Failed to get input count, hr %#x.\n", hr);
586 ok(count == 4, "Unexpected count %u.\n", count);
588 hr = IMFTopologyNode_SetOutputPrefType(node, 4, mediatype);
589 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
591 hr = IMFTopologyNode_GetInputCount(node, &count);
592 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
593 ok(count == 4, "Unexpected count %u.\n", count);
595 hr = IMFTopologyNode_GetOutputCount(node, &count);
596 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
597 ok(count == 5, "Unexpected count %u.\n", count);
599 IMFTopologyNode_Release(node);
601 IMFMediaType_Release(mediatype);
603 hr = IMFTopology_GetOutputNodeCollection(topology, &collection);
604 ok(hr == S_OK || broken(hr == E_FAIL) /* before Win8 */, "Failed to get output node collection, hr %#x.\n", hr);
605 if (SUCCEEDED(hr))
607 ok(!!collection, "Unexpected object pointer.\n");
608 hr = IMFCollection_GetElementCount(collection, &size);
609 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
610 ok(size == 1, "Unexpected item count.\n");
611 IMFCollection_Release(collection);
614 IMFTopology_Release(topology);
616 /* Connect nodes. */
617 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
618 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
620 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
621 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
623 EXPECT_REF(node, 1);
624 EXPECT_REF(node2, 1);
626 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
627 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
629 EXPECT_REF(node, 2);
630 EXPECT_REF(node2, 2);
632 IMFTopologyNode_Release(node);
634 EXPECT_REF(node, 1);
635 EXPECT_REF(node2, 2);
637 IMFTopologyNode_Release(node2);
639 EXPECT_REF(node, 1);
640 EXPECT_REF(node2, 1);
642 hr = IMFTopologyNode_GetNodeType(node2, &node_type);
643 ok(hr == S_OK, "Failed to get node type, hr %#x.\n", hr);
645 IMFTopologyNode_Release(node);
647 /* Connect within topology. */
648 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
649 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
651 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
652 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
654 hr = MFCreateTopology(&topology);
655 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
657 hr = IMFTopology_AddNode(topology, node);
658 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
660 hr = IMFTopology_AddNode(topology, node2);
661 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
663 EXPECT_REF(node, 2);
664 EXPECT_REF(node2, 2);
666 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
667 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
669 EXPECT_REF(node, 3);
670 EXPECT_REF(node2, 3);
672 hr = IMFTopology_Clear(topology);
673 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
675 EXPECT_REF(node, 1);
676 EXPECT_REF(node2, 1);
678 /* Removing connected node breaks connection. */
679 hr = IMFTopology_AddNode(topology, node);
680 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
682 hr = IMFTopology_AddNode(topology, node2);
683 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
685 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
686 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
688 hr = IMFTopology_RemoveNode(topology, node);
689 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
691 EXPECT_REF(node, 1);
692 EXPECT_REF(node2, 2);
694 hr = IMFTopologyNode_GetOutput(node, 0, &node3, &index);
695 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
697 hr = IMFTopology_AddNode(topology, node);
698 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
700 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 1);
701 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
703 hr = IMFTopology_RemoveNode(topology, node2);
704 ok(hr == S_OK, "Failed to remove a node, hr %#x.\n", hr);
706 EXPECT_REF(node, 2);
707 EXPECT_REF(node2, 1);
709 IMFTopologyNode_Release(node);
710 IMFTopologyNode_Release(node2);
712 /* Cloning nodes of different types. */
713 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
714 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
716 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
717 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
719 hr = IMFTopologyNode_CloneFrom(node, node2);
720 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
722 IMFTopologyNode_Release(node2);
724 /* Cloning preferred types. */
725 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
726 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
728 hr = MFCreateMediaType(&mediatype);
729 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
731 hr = IMFTopologyNode_SetOutputPrefType(node2, 0, mediatype);
732 ok(hr == S_OK, "Failed to set preferred type, hr %#x.\n", hr);
734 /* Vista checks for additional attributes. */
735 hr = IMFTopologyNode_CloneFrom(node, node2);
736 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
738 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
739 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
740 ok(mediatype == mediatype2, "Unexpected media type.\n");
742 IMFMediaType_Release(mediatype2);
743 IMFMediaType_Release(mediatype);
745 IMFTopologyNode_Release(node2);
747 /* Existing preferred types are not cleared. */
748 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node2);
749 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
751 hr = IMFTopologyNode_GetOutputCount(node, &count);
752 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
753 ok(count == 1, "Unexpected output count.\n");
755 hr = IMFTopologyNode_CloneFrom(node, node2);
756 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
758 hr = IMFTopologyNode_GetOutputCount(node, &count);
759 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
760 ok(count == 1, "Unexpected output count.\n");
762 hr = IMFTopologyNode_GetOutputPrefType(node, 0, &mediatype2);
763 ok(hr == S_OK, "Failed to get preferred type, hr %#x.\n", hr);
764 ok(!!mediatype2, "Unexpected media type.\n");
765 IMFMediaType_Release(mediatype2);
767 hr = IMFTopologyNode_CloneFrom(node2, node);
768 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Vista */, "Failed to clone a node, hr %#x.\n", hr);
770 hr = IMFTopologyNode_GetOutputCount(node2, &count);
771 ok(hr == S_OK, "Failed to get output count, hr %#x.\n", hr);
772 ok(count == 1, "Unexpected output count.\n");
774 IMFTopologyNode_Release(node2);
775 IMFTopologyNode_Release(node);
777 /* Add one node, connect to another that hasn't been added. */
778 hr = IMFTopology_Clear(topology);
779 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
781 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
782 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
784 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &node2);
785 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
787 hr = IMFTopology_AddNode(topology, node);
788 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
790 hr = IMFTopology_GetNodeCount(topology, &node_count);
791 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
792 ok(node_count == 1, "Unexpected node count.\n");
794 hr = IMFTopologyNode_ConnectOutput(node, 0, node2, 0);
795 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
797 hr = IMFTopology_GetNodeCount(topology, &node_count);
798 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
799 ok(node_count == 1, "Unexpected node count.\n");
801 IMFTopologyNode_Release(node);
802 IMFTopologyNode_Release(node2);
804 /* Add same node to different topologies. */
805 hr = IMFTopology_Clear(topology);
806 ok(hr == S_OK, "Failed to clear topology, hr %#x.\n", hr);
808 hr = MFCreateTopology(&topology2);
809 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
811 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &node);
812 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
814 hr = IMFTopology_AddNode(topology, node);
815 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
816 EXPECT_REF(node, 2);
818 hr = IMFTopology_GetNodeCount(topology, &node_count);
819 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
820 ok(node_count == 1, "Unexpected node count.\n");
822 hr = IMFTopology_GetNodeCount(topology2, &node_count);
823 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
824 ok(node_count == 0, "Unexpected node count.\n");
826 hr = IMFTopology_AddNode(topology2, node);
827 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
828 EXPECT_REF(node, 3);
830 hr = IMFTopology_GetNodeCount(topology, &node_count);
831 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
832 ok(node_count == 1, "Unexpected node count.\n");
834 hr = IMFTopology_GetNodeCount(topology2, &node_count);
835 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
836 ok(node_count == 1, "Unexpected node count.\n");
838 IMFTopology_Release(topology2);
839 IMFTopology_Release(topology);
842 static void test_topology_tee_node(void)
844 IMFTopologyNode *src_node, *tee_node;
845 IMFMediaType *mediatype, *mediatype2;
846 IMFTopology *topology;
847 unsigned int count;
848 HRESULT hr;
850 hr = MFCreateTopology(&topology);
851 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
853 hr = MFCreateMediaType(&mediatype);
854 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
856 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &tee_node);
857 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
859 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
860 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
862 hr = IMFTopologyNode_SetInputPrefType(tee_node, 0, mediatype);
863 ok(hr == S_OK, "Failed to set type, hr %#x.\n", hr);
865 /* Even though tee node has only one input and source has only one output,
866 it's possible to connect to higher inputs/outputs. */
868 /* SRC(0) -> TEE(0) */
869 hr = IMFTopologyNode_ConnectOutput(src_node, 0, tee_node, 0);
870 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
872 hr = IMFTopologyNode_GetInputCount(tee_node, &count);
873 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
874 ok(count == 1, "Unexpected count %u.\n", count);
876 hr = IMFTopologyNode_GetInputPrefType(tee_node, 0, &mediatype2);
877 ok(hr == S_OK, "Failed to get type, hr %#x.\n", hr);
878 ok(mediatype2 == mediatype, "Unexpected type.\n");
879 IMFMediaType_Release(mediatype2);
881 /* SRC(0) -> TEE(1) */
882 hr = IMFTopologyNode_ConnectOutput(src_node, 0, tee_node, 1);
883 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
885 hr = IMFTopologyNode_GetInputCount(tee_node, &count);
886 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
887 ok(count == 2, "Unexpected count %u.\n", count);
889 hr = IMFTopologyNode_SetInputPrefType(tee_node, 1, mediatype);
890 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
892 /* SRC(1) -> TEE(1) */
893 hr = IMFTopologyNode_ConnectOutput(src_node, 1, tee_node, 1);
894 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
896 hr = IMFTopologyNode_GetOutputCount(src_node, &count);
897 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
898 ok(count == 2, "Unexpected count %u.\n", count);
900 IMFMediaType_Release(mediatype);
901 IMFTopologyNode_Release(src_node);
902 IMFTopologyNode_Release(tee_node);
903 IMFTopology_Release(topology);
906 static HRESULT WINAPI test_getservice_QI(IMFGetService *iface, REFIID riid, void **obj)
908 if (IsEqualIID(riid, &IID_IMFGetService) || IsEqualIID(riid, &IID_IUnknown))
910 *obj = iface;
911 return S_OK;
914 *obj = NULL;
915 return E_NOINTERFACE;
918 static ULONG WINAPI test_getservice_AddRef(IMFGetService *iface)
920 return 2;
923 static ULONG WINAPI test_getservice_Release(IMFGetService *iface)
925 return 1;
928 static HRESULT WINAPI test_getservice_GetService(IMFGetService *iface, REFGUID service, REFIID riid, void **obj)
930 *obj = (void *)0xdeadbeef;
931 return 0x83eddead;
934 static const IMFGetServiceVtbl testmfgetservicevtbl =
936 test_getservice_QI,
937 test_getservice_AddRef,
938 test_getservice_Release,
939 test_getservice_GetService,
942 static IMFGetService test_getservice = { &testmfgetservicevtbl };
944 static HRESULT WINAPI testservice_QI(IUnknown *iface, REFIID riid, void **obj)
946 if (IsEqualIID(riid, &IID_IUnknown))
948 *obj = iface;
949 return S_OK;
952 *obj = NULL;
954 if (IsEqualIID(riid, &IID_IMFGetService))
955 return 0x82eddead;
957 return E_NOINTERFACE;
960 static HRESULT WINAPI testservice2_QI(IUnknown *iface, REFIID riid, void **obj)
962 if (IsEqualIID(riid, &IID_IUnknown))
964 *obj = iface;
965 return S_OK;
968 if (IsEqualIID(riid, &IID_IMFGetService))
970 *obj = &test_getservice;
971 return S_OK;
974 *obj = NULL;
975 return E_NOINTERFACE;
978 static ULONG WINAPI testservice_AddRef(IUnknown *iface)
980 return 2;
983 static ULONG WINAPI testservice_Release(IUnknown *iface)
985 return 1;
988 static const IUnknownVtbl testservicevtbl =
990 testservice_QI,
991 testservice_AddRef,
992 testservice_Release,
995 static const IUnknownVtbl testservice2vtbl =
997 testservice2_QI,
998 testservice_AddRef,
999 testservice_Release,
1002 static IUnknown testservice = { &testservicevtbl };
1003 static IUnknown testservice2 = { &testservice2vtbl };
1005 static void test_MFGetService(void)
1007 IUnknown *unk;
1008 HRESULT hr;
1010 hr = MFGetService(NULL, NULL, NULL, NULL);
1011 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
1013 unk = (void *)0xdeadbeef;
1014 hr = MFGetService(NULL, NULL, NULL, (void **)&unk);
1015 ok(hr == E_POINTER, "Unexpected return value %#x.\n", hr);
1016 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1018 hr = MFGetService(&testservice, NULL, NULL, NULL);
1019 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
1021 unk = (void *)0xdeadbeef;
1022 hr = MFGetService(&testservice, NULL, NULL, (void **)&unk);
1023 ok(hr == 0x82eddead, "Unexpected return value %#x.\n", hr);
1024 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1026 unk = NULL;
1027 hr = MFGetService(&testservice2, NULL, NULL, (void **)&unk);
1028 ok(hr == 0x83eddead, "Unexpected return value %#x.\n", hr);
1029 ok(unk == (void *)0xdeadbeef, "Unexpected out object.\n");
1032 static void test_sequencer_source(void)
1034 IMFSequencerSource *seq_source;
1035 HRESULT hr;
1037 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1038 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1040 hr = MFCreateSequencerSource(NULL, &seq_source);
1041 ok(hr == S_OK, "Failed to create sequencer source, hr %#x.\n", hr);
1043 check_interface(seq_source, &IID_IMFMediaSourceTopologyProvider, TRUE);
1045 IMFSequencerSource_Release(seq_source);
1047 hr = MFShutdown();
1048 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1051 struct test_callback
1053 IMFAsyncCallback IMFAsyncCallback_iface;
1056 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
1058 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
1059 IsEqualIID(riid, &IID_IUnknown))
1061 *obj = iface;
1062 IMFAsyncCallback_AddRef(iface);
1063 return S_OK;
1066 *obj = NULL;
1067 return E_NOINTERFACE;
1070 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
1072 return 2;
1075 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
1077 return 1;
1080 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
1082 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
1083 return E_NOTIMPL;
1086 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
1088 ok(result != NULL, "Unexpected result object.\n");
1090 return E_NOTIMPL;
1093 static const IMFAsyncCallbackVtbl testcallbackvtbl =
1095 testcallback_QueryInterface,
1096 testcallback_AddRef,
1097 testcallback_Release,
1098 testcallback_GetParameters,
1099 testcallback_Invoke,
1102 static void init_test_callback(struct test_callback *callback)
1104 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
1107 static void test_session_events(IMFMediaSession *session)
1109 struct test_callback callback, callback2;
1110 IMFAsyncResult *result;
1111 IMFMediaEvent *event;
1112 HRESULT hr;
1114 init_test_callback(&callback);
1115 init_test_callback(&callback2);
1117 hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event);
1118 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
1120 /* Async case. */
1121 hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL);
1122 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1124 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
1125 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
1127 /* Same callback, same state. */
1128 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session);
1129 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
1131 /* Same callback, different state. */
1132 hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
1133 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
1135 /* Different callback, same state. */
1136 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session);
1137 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
1139 /* Different callback, different state. */
1140 hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
1141 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
1143 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
1144 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
1146 hr = IMFMediaSession_EndGetEvent(session, result, &event);
1147 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
1149 /* Shutdown behavior. */
1150 hr = IMFMediaSession_Shutdown(session);
1151 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1154 static void test_media_session(void)
1156 IMFRateControl *rate_control, *rate_control2;
1157 IMFLocalMFTRegistration *local_reg;
1158 MFCLOCK_PROPERTIES clock_props;
1159 IMFRateSupport *rate_support;
1160 IMFAttributes *attributes;
1161 IMFMediaSession *session;
1162 IMFTopology *topology;
1163 IMFShutdown *shutdown;
1164 PROPVARIANT propvar;
1165 DWORD status, caps;
1166 IMFGetService *gs;
1167 IMFClock *clock;
1168 IUnknown *unk;
1169 HRESULT hr;
1170 float rate;
1171 BOOL thin;
1173 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1174 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1176 hr = MFCreateMediaSession(NULL, &session);
1177 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1179 hr = IMFMediaSession_QueryInterface(session, &IID_IMFAttributes, (void **)&unk);
1180 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1182 hr = IMFMediaSession_QueryInterface(session, &IID_IMFGetService, (void **)&gs);
1183 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
1185 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support);
1186 ok(hr == S_OK, "Failed to get rate support interface, hr %#x.\n", hr);
1188 hr = IMFGetService_GetService(gs, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, (void **)&rate_control);
1189 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
1191 hr = IMFGetService_GetService(gs, &MF_LOCAL_MFT_REGISTRATION_SERVICE, &IID_IMFLocalMFTRegistration,
1192 (void **)&local_reg);
1193 ok(hr == S_OK || broken(hr == E_NOINTERFACE) /* Vista */, "Failed to get registration service, hr %#x.\n", hr);
1194 if (SUCCEEDED(hr))
1195 IMFLocalMFTRegistration_Release(local_reg);
1197 hr = IMFRateSupport_QueryInterface(rate_support, &IID_IMFMediaSession, (void **)&unk);
1198 ok(hr == S_OK, "Failed to get session interface, hr %#x.\n", hr);
1199 ok(unk == (IUnknown *)session, "Unexpected pointer.\n");
1200 IUnknown_Release(unk);
1202 hr = IMFRateControl_GetRate(rate_control, NULL, NULL);
1203 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1205 rate = 0.0f;
1206 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
1207 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1208 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1210 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
1211 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1213 thin = TRUE;
1214 rate = 0.0f;
1215 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
1216 ok(hr == S_OK, "Failed to get playback rate, hr %#x.\n", hr);
1217 ok(!thin, "Unexpected thinning.\n");
1218 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1220 hr = IMFMediaSession_GetClock(session, &clock);
1221 ok(hr == S_OK, "Failed to get clock, hr %#x.\n", hr);
1223 hr = IMFClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control2);
1224 ok(hr == S_OK, "Failed to get rate control, hr %#x.\n", hr);
1226 rate = 0.0f;
1227 hr = IMFRateControl_GetRate(rate_control2, NULL, &rate);
1228 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
1229 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
1231 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.5f);
1232 todo_wine
1233 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
1235 IMFRateControl_Release(rate_control2);
1237 hr = IMFClock_GetProperties(clock, &clock_props);
1238 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
1239 IMFClock_Release(clock);
1241 IMFRateControl_Release(rate_control);
1242 IMFRateSupport_Release(rate_support);
1244 IMFGetService_Release(gs);
1246 IMFMediaSession_Release(session);
1248 hr = MFCreateMediaSession(NULL, &session);
1249 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1251 hr = IMFMediaSession_GetClock(session, &clock);
1252 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1254 hr = IMFClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
1255 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1257 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1258 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
1260 hr = IMFMediaSession_Shutdown(session);
1261 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1263 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
1264 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1265 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected shutdown status %u.\n", status);
1267 IMFShutdown_Release(shutdown);
1269 hr = IMFMediaSession_ClearTopologies(session);
1270 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1272 hr = IMFMediaSession_Start(session, &GUID_NULL, NULL);
1273 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1275 propvar.vt = VT_EMPTY;
1276 hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar);
1277 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1279 hr = IMFMediaSession_Pause(session);
1280 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1282 hr = IMFMediaSession_Stop(session);
1283 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1285 hr = IMFMediaSession_Close(session);
1286 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1288 hr = IMFMediaSession_GetClock(session, &clock);
1289 ok(hr == MF_E_SHUTDOWN || broken(hr == E_UNEXPECTED) /* Win7 */, "Unexpected hr %#x.\n", hr);
1291 hr = IMFMediaSession_GetSessionCapabilities(session, &caps);
1292 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1294 hr = IMFMediaSession_GetSessionCapabilities(session, NULL);
1295 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1297 hr = IMFMediaSession_GetFullTopology(session, MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology);
1298 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1300 hr = IMFMediaSession_Shutdown(session);
1301 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1303 IMFMediaSession_Release(session);
1305 /* Custom topology loader, GUID is not registered. */
1306 hr = MFCreateAttributes(&attributes, 1);
1307 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
1309 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_TOPOLOADER, &MF_SESSION_TOPOLOADER);
1310 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1312 hr = MFCreateMediaSession(attributes, &session);
1313 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1314 IMFMediaSession_Release(session);
1316 /* Disabled quality manager. */
1317 hr = IMFAttributes_SetGUID(attributes, &MF_SESSION_QUALITY_MANAGER, &GUID_NULL);
1318 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1320 hr = MFCreateMediaSession(attributes, &session);
1321 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1322 IMFMediaSession_Release(session);
1324 IMFAttributes_Release(attributes);
1326 /* Basic events behavior. */
1327 hr = MFCreateMediaSession(NULL, &session);
1328 ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
1330 test_session_events(session);
1332 IMFMediaSession_Release(session);
1334 hr = MFShutdown();
1335 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
1338 static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid,
1339 void **obj)
1341 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
1342 IsEqualIID(riid, &IID_IMFClockStateSink) ||
1343 IsEqualIID(riid, &IID_IUnknown))
1345 *obj = iface;
1346 IMFSampleGrabberSinkCallback_AddRef(iface);
1347 return S_OK;
1350 *obj = NULL;
1351 return E_NOINTERFACE;
1354 static ULONG WINAPI test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
1356 return 2;
1359 static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
1361 return 1;
1364 static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME systime,
1365 LONGLONG offset)
1367 return E_NOTIMPL;
1370 static HRESULT WINAPI test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1372 return E_NOTIMPL;
1375 static HRESULT WINAPI test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1377 return E_NOTIMPL;
1380 static HRESULT WINAPI test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME systime)
1382 return E_NOTIMPL;
1385 static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME systime, float rate)
1387 return E_NOTIMPL;
1390 static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
1391 IMFPresentationClock *clock)
1393 return E_NOTIMPL;
1396 static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
1397 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
1399 return E_NOTIMPL;
1402 static HRESULT WINAPI test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
1404 return E_NOTIMPL;
1407 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl =
1409 test_grabber_callback_QueryInterface,
1410 test_grabber_callback_AddRef,
1411 test_grabber_callback_Release,
1412 test_grabber_callback_OnClockStart,
1413 test_grabber_callback_OnClockStop,
1414 test_grabber_callback_OnClockPause,
1415 test_grabber_callback_OnClockRestart,
1416 test_grabber_callback_OnClockSetRate,
1417 test_grabber_callback_OnSetPresentationClock,
1418 test_grabber_callback_OnProcessSample,
1419 test_grabber_callback_OnShutdown,
1422 struct test_source
1424 IMFMediaSource IMFMediaSource_iface;
1425 LONG refcount;
1428 static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface)
1430 return CONTAINING_RECORD(iface, struct test_source, IMFMediaSource_iface);
1433 static HRESULT WINAPI test_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out)
1435 if (IsEqualIID(riid, &IID_IMFMediaSource)
1436 || IsEqualIID(riid, &IID_IMFMediaEventGenerator)
1437 || IsEqualIID(riid, &IID_IUnknown))
1439 *out = iface;
1441 else
1443 *out = NULL;
1444 return E_NOINTERFACE;
1447 IMFMediaSource_AddRef(iface);
1448 return S_OK;
1451 static ULONG WINAPI test_source_AddRef(IMFMediaSource *iface)
1453 struct test_source *source = impl_from_IMFMediaSource(iface);
1454 return InterlockedIncrement(&source->refcount);
1457 static ULONG WINAPI test_source_Release(IMFMediaSource *iface)
1459 struct test_source *source = impl_from_IMFMediaSource(iface);
1460 ULONG refcount = InterlockedDecrement(&source->refcount);
1462 if (!refcount)
1463 HeapFree(GetProcessHeap(), 0, source);
1465 return refcount;
1468 static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event)
1470 ok(0, "Unexpected call.\n");
1471 return E_NOTIMPL;
1474 static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state)
1476 ok(0, "Unexpected call.\n");
1477 return E_NOTIMPL;
1480 static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event)
1482 ok(0, "Unexpected call.\n");
1483 return E_NOTIMPL;
1486 static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type,
1487 HRESULT hr, const PROPVARIANT *value)
1489 ok(0, "Unexpected call.\n");
1490 return E_NOTIMPL;
1493 static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags)
1495 ok(0, "Unexpected call.\n");
1496 return E_NOTIMPL;
1499 static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd)
1501 ok(0, "Unexpected call.\n");
1502 return E_NOTIMPL;
1505 static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format,
1506 const PROPVARIANT *start_position)
1508 ok(0, "Unexpected call.\n");
1509 return E_NOTIMPL;
1512 static HRESULT WINAPI test_source_Stop(IMFMediaSource *iface)
1514 ok(0, "Unexpected call.\n");
1515 return E_NOTIMPL;
1518 static HRESULT WINAPI test_source_Pause(IMFMediaSource *iface)
1520 ok(0, "Unexpected call.\n");
1521 return E_NOTIMPL;
1524 static HRESULT WINAPI test_source_Shutdown(IMFMediaSource *iface)
1526 ok(0, "Unexpected call.\n");
1527 return E_NOTIMPL;
1530 static const IMFMediaSourceVtbl test_source_vtbl =
1532 test_source_QueryInterface,
1533 test_source_AddRef,
1534 test_source_Release,
1535 test_source_GetEvent,
1536 test_source_BeginGetEvent,
1537 test_source_EndGetEvent,
1538 test_source_QueueEvent,
1539 test_source_GetCharacteristics,
1540 test_source_CreatePresentationDescriptor,
1541 test_source_Start,
1542 test_source_Stop,
1543 test_source_Pause,
1544 test_source_Shutdown,
1547 static IMFMediaSource *create_test_source(void)
1549 struct test_source *source;
1551 source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*source));
1552 source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl;
1553 source->refcount = 1;
1555 return &source->IMFMediaSource_iface;
1558 struct type_attr
1560 const GUID *key;
1561 unsigned int value;
1564 static void init_media_type(IMFMediaType *mediatype, const GUID *major, const struct type_attr *attrs)
1566 HRESULT hr;
1568 hr = IMFMediaType_DeleteAllItems(mediatype);
1569 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1571 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major);
1572 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1574 while (attrs->key)
1576 if (IsEqualGUID(attrs->key, &MF_MT_SUBTYPE))
1578 GUID subtype;
1580 memcpy(&subtype, IsEqualGUID(major, &MFMediaType_Audio) ? &MFAudioFormat_Base : &MFVideoFormat_Base,
1581 sizeof(subtype));
1582 subtype.Data1 = attrs->value;
1583 hr = IMFMediaType_SetGUID(mediatype, attrs->key, &subtype);
1585 else
1586 hr = IMFMediaType_SetUINT32(mediatype, attrs->key, attrs->value);
1587 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1589 attrs++;
1593 static void init_source_node(IMFMediaType *mediatype, IMFMediaSource *source, IMFTopologyNode *node)
1595 IMFPresentationDescriptor *pd;
1596 IMFMediaTypeHandler *handler;
1597 IMFStreamDescriptor *sd;
1598 HRESULT hr;
1600 hr = IMFTopologyNode_DeleteAllItems(node);
1601 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1603 hr = MFCreateStreamDescriptor(0, 1, &mediatype, &sd);
1604 ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr);
1606 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
1607 ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr);
1609 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype);
1610 ok(hr == S_OK, "Failed to set current media type, hr %#x.\n", hr);
1612 IMFMediaTypeHandler_Release(handler);
1614 hr = MFCreatePresentationDescriptor(1, &sd, &pd);
1615 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
1617 hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
1618 ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
1620 IMFPresentationDescriptor_Release(pd);
1622 hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
1623 ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
1625 if (source)
1627 hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
1628 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1631 IMFStreamDescriptor_Release(sd);
1634 static void init_sink_node(IMFActivate *sink_activate, unsigned int method, IMFTopologyNode *node)
1636 IMFStreamSink *stream_sink;
1637 IMFMediaSink *sink;
1638 HRESULT hr;
1640 hr = IMFTopologyNode_DeleteAllItems(node);
1641 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1643 hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
1644 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
1646 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
1647 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1649 IMFMediaSink_Release(sink);
1651 hr = IMFTopologyNode_SetObject(node, (IUnknown *)stream_sink);
1652 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1654 IMFStreamSink_Release(stream_sink);
1656 hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method);
1657 ok(hr == S_OK, "Failed to set connect method, hr %#x.\n", hr);
1660 enum loader_test_flags
1662 LOADER_EXPECTED_DECODER = 0x1,
1663 LOADER_EXPECTED_CONVERTER = 0x2,
1664 LOADER_TODO = 0x4,
1667 static void test_topology_loader(void)
1669 static const struct loader_test
1671 const GUID *major;
1672 struct
1674 struct type_attr attrs[8];
1675 } input_type;
1676 struct
1678 struct type_attr attrs[8];
1679 } output_type;
1681 MF_CONNECT_METHOD method;
1682 HRESULT expected_result;
1683 unsigned int flags;
1685 loader_tests[] =
1688 /* PCM -> PCM, same type */
1689 &MFMediaType_Audio,
1692 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1693 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1694 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1695 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1696 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1697 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1702 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1703 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1704 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1705 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1706 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1707 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1711 MF_CONNECT_DIRECT,
1712 S_OK,
1716 /* PCM -> PCM, different bps. */
1717 &MFMediaType_Audio,
1720 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1721 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1722 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1723 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1724 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1725 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1730 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1731 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1732 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 },
1733 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 },
1734 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1735 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1739 MF_CONNECT_DIRECT,
1740 MF_E_INVALIDMEDIATYPE,
1744 /* PCM -> PCM, different bps. */
1745 &MFMediaType_Audio,
1748 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1749 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1750 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1751 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1752 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1753 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1758 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1759 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1760 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 },
1761 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 },
1762 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1763 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1767 MF_CONNECT_ALLOW_CONVERTER,
1768 S_OK,
1769 LOADER_EXPECTED_CONVERTER | LOADER_TODO,
1773 /* MP3 -> PCM */
1774 &MFMediaType_Audio,
1777 { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 },
1778 { &MF_MT_AUDIO_NUM_CHANNELS, 2 },
1779 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1780 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 },
1781 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1786 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1787 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1788 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1789 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1790 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1791 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1795 MF_CONNECT_DIRECT,
1796 MF_E_INVALIDMEDIATYPE,
1800 /* MP3 -> PCM */
1801 &MFMediaType_Audio,
1804 { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 },
1805 { &MF_MT_AUDIO_NUM_CHANNELS, 2 },
1806 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1807 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 },
1808 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1813 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1814 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1815 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1816 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1817 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1818 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1822 MF_CONNECT_ALLOW_CONVERTER,
1823 MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION,
1824 LOADER_TODO,
1828 /* MP3 -> PCM */
1829 &MFMediaType_Audio,
1832 { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 },
1833 { &MF_MT_AUDIO_NUM_CHANNELS, 2 },
1834 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1835 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 },
1836 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1841 { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM },
1842 { &MF_MT_AUDIO_NUM_CHANNELS, 1 },
1843 { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 },
1844 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 },
1845 { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 },
1846 { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 },
1850 MF_CONNECT_ALLOW_DECODER,
1851 S_OK,
1852 LOADER_EXPECTED_DECODER | LOADER_TODO,
1856 IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl };
1857 IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node;
1858 IMFTopology *topology, *topology2, *full_topology;
1859 IMFMediaType *media_type, *input_type, *output_type;
1860 unsigned int i, count, value, index;
1861 IMFPresentationDescriptor *pd;
1862 IMFActivate *sink_activate;
1863 MF_TOPOLOGY_TYPE node_type;
1864 IMFStreamDescriptor *sd;
1865 IMFTransform *transform;
1866 IMFMediaSource *source;
1867 IMFTopoLoader *loader;
1868 IUnknown *node_object;
1869 WORD node_count;
1870 TOPOID node_id;
1871 HRESULT hr;
1872 BOOL ret;
1874 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1875 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
1877 hr = MFCreateTopoLoader(NULL);
1878 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1880 hr = MFCreateTopoLoader(&loader);
1881 ok(hr == S_OK, "Failed to create topology loader, hr %#x.\n", hr);
1883 hr = MFCreateTopology(&topology);
1884 ok(hr == S_OK, "Failed to create topology, hr %#x.\n", hr);
1886 /* Empty topology */
1887 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1888 todo_wine
1889 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1891 /* Add source node. */
1892 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
1893 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
1895 /* When a decoder is involved, windows requires this attribute to be present */
1896 source = create_test_source();
1898 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
1899 ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
1901 hr = MFCreateMediaType(&media_type);
1902 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1904 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1905 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1906 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
1907 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1909 hr = MFCreateStreamDescriptor(0, 1, &media_type, &sd);
1910 ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr);
1912 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd);
1913 ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
1915 hr = MFCreatePresentationDescriptor(1, &sd, &pd);
1916 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
1918 hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
1919 ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
1921 IMFPresentationDescriptor_Release(pd);
1922 IMFStreamDescriptor_Release(sd);
1923 IMFMediaType_Release(media_type);
1925 hr = IMFTopology_AddNode(topology, src_node);
1926 ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr);
1928 /* Source node only. */
1929 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1930 todo_wine
1931 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1933 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
1934 ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr);
1936 hr = MFCreateMediaType(&media_type);
1937 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1939 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1940 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1941 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
1942 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1944 hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate);
1945 ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
1947 hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate);
1948 ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
1950 IMFMediaType_Release(media_type);
1952 hr = IMFTopology_AddNode(topology, sink_node);
1953 ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
1955 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1956 todo_wine
1957 ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1959 hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
1960 ok(hr == S_OK, "Failed to connect nodes, hr %#x.\n", hr);
1962 /* Sink was not resolved. */
1963 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1964 ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
1966 hr = MFCreateMediaType(&input_type);
1967 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1969 hr = MFCreateMediaType(&output_type);
1970 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1972 for (i = 0; i < ARRAY_SIZE(loader_tests); ++i)
1974 const struct loader_test *test = &loader_tests[i];
1976 init_media_type(input_type, test->major, test->input_type.attrs);
1977 init_media_type(output_type, test->major, test->output_type.attrs);
1979 hr = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate);
1980 ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
1982 init_source_node(input_type, source, src_node);
1983 init_sink_node(sink_activate, test->method, sink_node);
1985 hr = IMFTopology_GetCount(topology, &count);
1986 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1987 ok(!count, "Unexpected count %u.\n", count);
1989 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
1990 todo_wine_if(test->flags & LOADER_TODO)
1991 ok(hr == test->expected_result, "Unexpected hr %#x on test %u.\n", hr, i);
1992 ok(full_topology != topology, "Unexpected instance.\n");
1994 if (test->expected_result == S_OK && hr == S_OK)
1996 hr = IMFTopology_GetCount(full_topology, &count);
1997 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
1998 todo_wine
1999 ok(count == 1, "Unexpected count %u.\n", count);
2001 value = 0xdeadbeef;
2002 hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value);
2003 todo_wine {
2004 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2005 ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
2007 count = 2;
2008 if (test->flags & LOADER_EXPECTED_DECODER)
2009 count++;
2010 if (test->flags & LOADER_EXPECTED_CONVERTER)
2011 count++;
2013 hr = IMFTopology_GetNodeCount(full_topology, &node_count);
2014 ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
2015 todo_wine_if(test->flags & (LOADER_EXPECTED_CONVERTER | LOADER_EXPECTED_DECODER))
2016 ok(node_count == count, "Unexpected node count %u.\n", node_count);
2018 hr = IMFTopologyNode_GetTopoNodeID(src_node, &node_id);
2019 ok(hr == S_OK, "Failed to get source node id, hr %#x.\n", hr);
2021 hr = IMFTopology_GetNodeByID(full_topology, node_id, &src_node2);
2022 ok(hr == S_OK, "Failed to get source in resolved topology, hr %#x.\n", hr);
2024 hr = IMFTopologyNode_GetTopoNodeID(sink_node, &node_id);
2025 ok(hr == S_OK, "Failed to get sink node id, hr %#x.\n", hr);
2027 hr = IMFTopology_GetNodeByID(full_topology, node_id, &sink_node2);
2028 ok(hr == S_OK, "Failed to get sink in resolved topology, hr %#x.\n", hr);
2030 if (test->flags & (LOADER_EXPECTED_DECODER | LOADER_EXPECTED_CONVERTER) && strcmp(winetest_platform, "wine"))
2032 hr = IMFTopologyNode_GetOutput(src_node2, 0, &mft_node, &index);
2033 ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr);
2034 ok(!index, "Unexpected stream index %u.\n", index);
2036 hr = IMFTopologyNode_GetNodeType(mft_node, &node_type);
2037 ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr);
2038 ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u.\n", node_type);
2040 hr = IMFTopologyNode_GetObject(mft_node, &node_object);
2041 ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr);
2043 if (test->flags & LOADER_EXPECTED_DECODER)
2045 value = 0;
2046 hr = IMFTopologyNode_GetUINT32(mft_node, &MF_TOPONODE_DECODER, &value);
2047 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2048 ok(value == 1, "Unexpected value.\n");
2051 hr = IMFTopologyNode_GetItem(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, NULL);
2052 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2054 hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void **)&transform);
2055 ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr);
2056 IUnknown_Release(node_object);
2058 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
2059 ok(hr == S_OK, "Failed to get transform input type, hr %#x.\n", hr);
2061 hr = IMFMediaType_Compare(input_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret);
2062 ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr);
2063 ok(ret, "Input type of first transform doesn't match source node type.\n");
2065 IMFTopologyNode_Release(mft_node);
2066 IMFMediaType_Release(media_type);
2067 IMFTransform_Release(transform);
2069 hr = IMFTopologyNode_GetInput(sink_node2, 0, &mft_node, &index);
2070 ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr);
2071 ok(!index, "Unexpected stream index %u.\n", index);
2073 hr = IMFTopologyNode_GetNodeType(mft_node, &node_type);
2074 ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr);
2075 ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u.\n", node_type);
2077 hr = IMFTopologyNode_GetItem(mft_node, &MF_TOPONODE_TRANSFORM_OBJECTID, NULL);
2078 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2080 hr = IMFTopologyNode_GetObject(mft_node, &node_object);
2081 ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr);
2083 hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void**) &transform);
2084 ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr);
2085 IUnknown_Release(node_object);
2087 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
2088 ok(hr == S_OK, "Failed to get transform output type, hr %#x.\n", hr);
2090 hr = IMFMediaType_Compare(output_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret);
2091 ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr);
2092 ok(ret, "Output type of last transform doesn't match sink node type.\n");
2094 IMFTopologyNode_Release(mft_node);
2095 IMFMediaType_Release(media_type);
2096 IMFTransform_Release(transform);
2099 IMFTopologyNode_Release(sink_node2);
2101 hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
2102 ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
2103 ok(full_topology != topology2, "Unexpected instance.\n");
2105 IMFTopology_Release(topology2);
2106 IMFTopology_Release(full_topology);
2109 hr = IMFTopology_GetCount(topology, &count);
2110 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
2111 ok(!count, "Unexpected count %u.\n", count);
2113 IMFActivate_ShutdownObject(sink_activate);
2114 IMFActivate_Release(sink_activate);
2117 IMFMediaType_Release(input_type);
2118 IMFMediaType_Release(output_type);
2120 IMFMediaSource_Release(source);
2121 IMFTopoLoader_Release(loader);
2123 hr = MFShutdown();
2124 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
2127 static void test_topology_loader_evr(void)
2129 IMFTopologyNode *node, *source_node, *evr_node;
2130 IMFTopology *topology, *full_topology;
2131 IMFMediaTypeHandler *handler;
2132 unsigned int i, count, value;
2133 IMFStreamSink *stream_sink;
2134 IMFMediaType *media_type;
2135 IMFActivate *activate;
2136 IMFTopoLoader *loader;
2137 IMFMediaSink *sink;
2138 WORD node_count;
2139 UINT64 value64;
2140 HWND window;
2141 HRESULT hr;
2143 hr = CoInitialize(NULL);
2144 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
2146 hr = MFCreateTopoLoader(&loader);
2147 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2149 /* Source node. */
2150 hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &source_node);
2151 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
2153 hr = MFCreateMediaType(&media_type);
2154 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2156 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
2157 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2158 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
2159 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2160 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
2161 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2162 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
2163 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2165 init_source_node(media_type, NULL, source_node);
2167 /* EVR sink node. */
2168 window = create_window();
2170 hr = MFCreateVideoRendererActivate(window, &activate);
2171 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
2173 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2174 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2176 hr = IMFMediaSink_GetStreamSinkById(sink, 0, &stream_sink);
2177 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2179 hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &evr_node);
2180 ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
2182 hr = IMFTopologyNode_SetObject(evr_node, (IUnknown *)stream_sink);
2183 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2185 hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler);
2186 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2187 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
2188 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2189 IMFMediaTypeHandler_Release(handler);
2191 IMFStreamSink_Release(stream_sink);
2192 IMFMediaSink_Release(sink);
2194 hr = MFCreateTopology(&topology);
2195 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2197 hr = IMFTopology_AddNode(topology, source_node);
2198 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2199 hr = IMFTopology_AddNode(topology, evr_node);
2200 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2201 hr = IMFTopologyNode_ConnectOutput(source_node, 0, evr_node, 0);
2202 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2204 hr = IMFTopologyNode_SetUINT32(evr_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_DIRECT);
2205 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2207 hr = IMFTopologyNode_GetCount(evr_node, &count);
2208 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2209 ok(count == 1, "Unexpected attribute count %u.\n", count);
2211 hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
2212 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2214 hr = IMFTopology_GetNodeCount(full_topology, &node_count);
2215 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2216 todo_wine
2217 ok(node_count == 3, "Unexpected node count %u.\n", node_count);
2219 for (i = 0; i < node_count; ++i)
2221 MF_TOPOLOGY_TYPE node_type;
2223 hr = IMFTopology_GetNode(full_topology, i, &node);
2224 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2226 hr = IMFTopologyNode_GetNodeType(node, &node_type);
2227 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2229 if (node_type == MF_TOPOLOGY_OUTPUT_NODE)
2231 value = 1;
2232 hr = IMFTopologyNode_GetUINT32(node, &MF_TOPONODE_STREAMID, &value);
2233 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2234 ok(!value, "Unexpected stream id %u.\n", value);
2236 else if (node_type == MF_TOPOLOGY_SOURCESTREAM_NODE)
2238 value64 = 1;
2239 hr = IMFTopologyNode_GetUINT64(node, &MF_TOPONODE_MEDIASTART, &value64);
2240 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2241 ok(!value64, "Unexpected value.\n");
2245 IMFTopology_Release(full_topology);
2247 IMFTopoLoader_Release(loader);
2249 IMFTopologyNode_Release(source_node);
2250 IMFTopologyNode_Release(evr_node);
2251 IMFTopology_Release(topology);
2252 IMFMediaType_Release(media_type);
2253 DestroyWindow(window);
2255 CoUninitialize();
2258 static HRESULT WINAPI testshutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **obj)
2260 if (IsEqualIID(riid, &IID_IMFShutdown) ||
2261 IsEqualIID(riid, &IID_IUnknown))
2263 *obj = iface;
2264 IMFShutdown_AddRef(iface);
2265 return S_OK;
2268 *obj = NULL;
2269 return E_NOINTERFACE;
2272 static ULONG WINAPI testshutdown_AddRef(IMFShutdown *iface)
2274 return 2;
2277 static ULONG WINAPI testshutdown_Release(IMFShutdown *iface)
2279 return 1;
2282 static HRESULT WINAPI testshutdown_Shutdown(IMFShutdown *iface)
2284 return 0xdead;
2287 static HRESULT WINAPI testshutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status)
2289 ok(0, "Unexpected call.\n");
2290 return E_NOTIMPL;
2293 static const IMFShutdownVtbl testshutdownvtbl =
2295 testshutdown_QueryInterface,
2296 testshutdown_AddRef,
2297 testshutdown_Release,
2298 testshutdown_Shutdown,
2299 testshutdown_GetShutdownStatus,
2302 static void test_MFShutdownObject(void)
2304 IMFShutdown testshutdown = { &testshutdownvtbl };
2305 IUnknown testshutdown2 = { &testservicevtbl };
2306 HRESULT hr;
2308 hr = MFShutdownObject(NULL);
2309 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2311 hr = MFShutdownObject((IUnknown *)&testshutdown);
2312 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2314 hr = MFShutdownObject(&testshutdown2);
2315 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2318 enum clock_action
2320 CLOCK_START,
2321 CLOCK_STOP,
2322 CLOCK_PAUSE,
2325 static HRESULT WINAPI test_clock_sink_QueryInterface(IMFClockStateSink *iface, REFIID riid, void **obj)
2327 if (IsEqualIID(riid, &IID_IMFClockStateSink) ||
2328 IsEqualIID(riid, &IID_IUnknown))
2330 *obj = iface;
2331 IMFClockStateSink_AddRef(iface);
2332 return S_OK;
2335 *obj = NULL;
2336 return E_NOINTERFACE;
2339 static ULONG WINAPI test_clock_sink_AddRef(IMFClockStateSink *iface)
2341 return 2;
2344 static ULONG WINAPI test_clock_sink_Release(IMFClockStateSink *iface)
2346 return 1;
2349 static HRESULT WINAPI test_clock_sink_OnClockStart(IMFClockStateSink *iface, MFTIME system_time, LONGLONG offset)
2351 return E_NOTIMPL;
2354 static HRESULT WINAPI test_clock_sink_OnClockStop(IMFClockStateSink *iface, MFTIME system_time)
2356 return E_NOTIMPL;
2359 static HRESULT WINAPI test_clock_sink_OnClockPause(IMFClockStateSink *iface, MFTIME system_time)
2361 return E_NOTIMPL;
2364 static HRESULT WINAPI test_clock_sink_OnClockRestart(IMFClockStateSink *iface, MFTIME system_time)
2366 return E_NOTIMPL;
2369 static HRESULT WINAPI test_clock_sink_OnClockSetRate(IMFClockStateSink *iface, MFTIME system_time, float rate)
2371 return E_NOTIMPL;
2374 static const IMFClockStateSinkVtbl test_clock_sink_vtbl =
2376 test_clock_sink_QueryInterface,
2377 test_clock_sink_AddRef,
2378 test_clock_sink_Release,
2379 test_clock_sink_OnClockStart,
2380 test_clock_sink_OnClockStop,
2381 test_clock_sink_OnClockPause,
2382 test_clock_sink_OnClockRestart,
2383 test_clock_sink_OnClockSetRate,
2386 static void test_presentation_clock(void)
2388 static const struct clock_state_test
2390 enum clock_action action;
2391 MFCLOCK_STATE clock_state;
2392 MFCLOCK_STATE source_state;
2393 HRESULT hr;
2395 clock_state_change[] =
2397 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID },
2398 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_INVALIDREQUEST },
2399 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_INVALID, MF_E_CLOCK_STATE_ALREADY_SET },
2400 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
2401 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
2402 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
2403 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED, MF_E_CLOCK_STATE_ALREADY_SET },
2404 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
2405 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
2406 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED },
2407 { CLOCK_STOP, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_CLOCK_STATE_ALREADY_SET },
2408 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, MFCLOCK_STATE_STOPPED, MF_E_INVALIDREQUEST },
2409 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
2410 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, MFCLOCK_STATE_PAUSED },
2411 { CLOCK_START, MFCLOCK_STATE_RUNNING, MFCLOCK_STATE_RUNNING },
2413 IMFClockStateSink test_sink = { &test_clock_sink_vtbl };
2414 IMFPresentationTimeSource *time_source;
2415 MFCLOCK_PROPERTIES props, props2;
2416 IMFRateControl *rate_control;
2417 IMFPresentationClock *clock;
2418 MFSHUTDOWN_STATUS status;
2419 IMFShutdown *shutdown;
2420 MFTIME systime, time;
2421 LONGLONG clock_time;
2422 MFCLOCK_STATE state;
2423 unsigned int i;
2424 DWORD value;
2425 float rate;
2426 HRESULT hr;
2427 BOOL thin;
2429 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2430 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2432 hr = MFCreatePresentationClock(&clock);
2433 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
2435 check_interface(clock, &IID_IMFTimer, TRUE);
2436 check_interface(clock, &IID_IMFRateControl, TRUE);
2437 check_interface(clock, &IID_IMFPresentationClock, TRUE);
2438 check_interface(clock, &IID_IMFShutdown, TRUE);
2439 check_interface(clock, &IID_IMFClock, TRUE);
2441 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control);
2442 ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr);
2444 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
2445 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2447 hr = IMFPresentationClock_GetTimeSource(clock, NULL);
2448 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2450 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
2451 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2453 hr = IMFPresentationClock_GetClockCharacteristics(clock, NULL);
2454 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2456 hr = IMFPresentationClock_GetTime(clock, &time);
2457 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2459 hr = IMFPresentationClock_GetTime(clock, NULL);
2460 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2462 value = 1;
2463 hr = IMFPresentationClock_GetContinuityKey(clock, &value);
2464 ok(hr == S_OK, "Failed to get continuity key, hr %#x.\n", hr);
2465 ok(value == 0, "Unexpected value %u.\n", value);
2467 hr = IMFPresentationClock_GetProperties(clock, &props);
2468 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2470 hr = IMFPresentationClock_GetState(clock, 0, &state);
2471 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
2472 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
2474 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &clock_time, &systime);
2475 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2477 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, NULL, &systime);
2478 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2480 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, NULL);
2481 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2483 /* Sinks. */
2484 hr = IMFPresentationClock_AddClockStateSink(clock, NULL);
2485 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2487 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
2488 ok(hr == S_OK, "Failed to add a sink, hr %#x.\n", hr);
2490 hr = IMFPresentationClock_AddClockStateSink(clock, &test_sink);
2491 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2493 hr = IMFPresentationClock_RemoveClockStateSink(clock, NULL);
2494 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2496 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
2497 ok(hr == S_OK, "Failed to remove sink, hr %#x.\n", hr);
2499 hr = IMFPresentationClock_RemoveClockStateSink(clock, &test_sink);
2500 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2502 /* State change commands, time source is not set yet. */
2503 hr = IMFPresentationClock_Start(clock, 0);
2504 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2506 hr = IMFPresentationClock_Pause(clock);
2507 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2509 hr = IMFPresentationClock_Stop(clock);
2510 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2512 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
2513 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
2515 /* Set default time source. */
2516 hr = MFCreateSystemTimeSource(&time_source);
2517 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2519 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
2520 ok(hr == S_OK, "Failed to get time source flags, hr %#x.\n", hr);
2521 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
2522 "Unexpected clock flags %#x.\n", value);
2524 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
2525 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
2527 hr = IMFPresentationTimeSource_GetProperties(time_source, &props2);
2528 ok(hr == S_OK, "Failed to get time source properties, hr %#x.\n", hr);
2530 hr = IMFPresentationClock_GetClockCharacteristics(clock, &value);
2531 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
2532 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
2533 "Unexpected clock flags %#x.\n", value);
2535 hr = IMFPresentationClock_GetProperties(clock, &props);
2536 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
2537 ok(!memcmp(&props, &props2, sizeof(props)), "Unexpected clock properties.\n");
2539 /* State changes. */
2540 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
2542 switch (clock_state_change[i].action)
2544 case CLOCK_STOP:
2545 hr = IMFPresentationClock_Stop(clock);
2546 break;
2547 case CLOCK_PAUSE:
2548 hr = IMFPresentationClock_Pause(clock);
2549 break;
2550 case CLOCK_START:
2551 hr = IMFPresentationClock_Start(clock, 0);
2552 break;
2553 default:
2556 ok(hr == clock_state_change[i].hr, "%u: unexpected hr %#x.\n", i, hr);
2558 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2559 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
2560 ok(state == clock_state_change[i].source_state, "%u: unexpected state %d.\n", i, state);
2562 hr = IMFPresentationClock_GetState(clock, 0, &state);
2563 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
2564 ok(state == clock_state_change[i].clock_state, "%u: unexpected state %d.\n", i, state);
2567 /* Clock time stamps. */
2568 hr = IMFPresentationClock_Start(clock, 10);
2569 ok(hr == S_OK, "Failed to start presentation clock, hr %#x.\n", hr);
2571 hr = IMFPresentationClock_Pause(clock);
2572 ok(hr == S_OK, "Failed to pause presentation clock, hr %#x.\n", hr);
2574 hr = IMFPresentationClock_GetTime(clock, &time);
2575 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
2577 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &clock_time, &systime);
2578 ok(hr == S_OK, "Failed to get time source time, hr %#x.\n", hr);
2579 ok(time == clock_time, "Unexpected clock time.\n");
2581 hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &time, &systime);
2582 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
2583 ok(time == clock_time, "Unexpected clock time.\n");
2585 IMFPresentationTimeSource_Release(time_source);
2587 hr = IMFRateControl_GetRate(rate_control, NULL, &rate);
2588 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
2590 hr = IMFRateControl_GetRate(rate_control, &thin, NULL);
2591 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2593 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
2594 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
2595 ok(rate == 1.0f, "Unexpected rate.\n");
2596 ok(!thin, "Unexpected thinning.\n");
2598 hr = IMFPresentationClock_GetState(clock, 0, &state);
2599 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2600 ok(state == MFCLOCK_STATE_PAUSED, "Unexpected state %d.\n", state);
2602 hr = IMFPresentationClock_Start(clock, 0);
2603 ok(hr == S_OK, "Failed to stop, hr %#x.\n", hr);
2605 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
2606 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
2607 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
2608 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
2609 ok(rate == 0.0f, "Unexpected rate.\n");
2610 hr = IMFRateControl_SetRate(rate_control, FALSE, 1.0f);
2611 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
2612 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.0f);
2613 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
2614 hr = IMFRateControl_SetRate(rate_control, FALSE, 0.5f);
2615 ok(hr == S_OK, "Failed to set clock rate, hr %#x.\n", hr);
2616 hr = IMFRateControl_SetRate(rate_control, TRUE, -1.0f);
2617 ok(hr == MF_E_THINNING_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
2619 hr = IMFPresentationClock_GetState(clock, 0, &state);
2620 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2621 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
2623 hr = IMFRateControl_GetRate(rate_control, &thin, &rate);
2624 ok(hr == S_OK, "Failed to get clock rate, hr %#x.\n", hr);
2625 ok(rate == 0.5f, "Unexpected rate.\n");
2626 ok(!thin, "Unexpected thinning.\n");
2628 IMFRateControl_Release(rate_control);
2630 hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown);
2631 ok(hr == S_OK, "Failed to get shutdown interface, hr %#x.\n", hr);
2633 /* Shutdown behavior. */
2634 hr = IMFShutdown_GetShutdownStatus(shutdown, NULL);
2635 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2637 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2638 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
2640 hr = IMFShutdown_Shutdown(shutdown);
2641 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2643 time_source = NULL;
2644 hr = IMFPresentationClock_GetTimeSource(clock, &time_source);
2645 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2646 ok(!!time_source, "Unexpected instance %p.\n", time_source);
2647 IMFPresentationTimeSource_Release(time_source);
2649 hr = IMFPresentationClock_GetTime(clock, &time);
2650 ok(hr == S_OK, "Failed to get time, hr %#x.\n", hr);
2652 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2653 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
2654 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
2656 hr = IMFPresentationClock_Start(clock, 0);
2657 ok(hr == S_OK, "Failed to start the clock, hr %#x.\n", hr);
2659 hr = IMFShutdown_GetShutdownStatus(shutdown, &status);
2660 ok(hr == S_OK, "Failed to get status, hr %#x.\n", hr);
2661 ok(status == MFSHUTDOWN_COMPLETED, "Unexpected status.\n");
2663 hr = IMFShutdown_Shutdown(shutdown);
2664 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2666 IMFShutdown_Release(shutdown);
2668 IMFPresentationClock_Release(clock);
2670 hr = MFShutdown();
2671 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2674 static HRESULT WINAPI grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, void **obj)
2676 if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) ||
2677 IsEqualIID(riid, &IID_IMFClockStateSink) ||
2678 IsEqualIID(riid, &IID_IUnknown))
2680 *obj = iface;
2681 IMFSampleGrabberSinkCallback_AddRef(iface);
2682 return S_OK;
2685 *obj = NULL;
2686 return E_NOINTERFACE;
2689 static ULONG WINAPI grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface)
2691 return 2;
2694 static ULONG WINAPI grabber_callback_Release(IMFSampleGrabberSinkCallback *iface)
2696 return 1;
2699 static HRESULT WINAPI grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset)
2701 return E_NOTIMPL;
2704 static HRESULT WINAPI grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2706 return E_NOTIMPL;
2709 static HRESULT WINAPI grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2711 return E_NOTIMPL;
2714 static HRESULT WINAPI grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME time)
2716 return E_NOTIMPL;
2719 static HRESULT WINAPI grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME time, float rate)
2721 return E_NOTIMPL;
2724 static HRESULT WINAPI grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface,
2725 IMFPresentationClock *clock)
2727 return S_OK;
2730 static HRESULT WINAPI grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type,
2731 DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size)
2733 return E_NOTIMPL;
2736 static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface)
2738 return S_OK;
2741 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl =
2743 grabber_callback_QueryInterface,
2744 grabber_callback_AddRef,
2745 grabber_callback_Release,
2746 grabber_callback_OnClockStart,
2747 grabber_callback_OnClockStop,
2748 grabber_callback_OnClockPause,
2749 grabber_callback_OnClockRestart,
2750 grabber_callback_OnClockSetRate,
2751 grabber_callback_OnSetPresentationClock,
2752 grabber_callback_OnProcessSample,
2753 grabber_callback_OnShutdown,
2756 static IMFSampleGrabberSinkCallback grabber_callback = { &grabber_callback_vtbl };
2758 static void test_sample_grabber(void)
2760 IMFMediaType *media_type, *media_type2, *media_type3;
2761 IMFMediaTypeHandler *handler, *handler2;
2762 IMFPresentationTimeSource *time_source;
2763 IMFPresentationClock *clock, *clock2;
2764 IMFStreamSink *stream, *stream2;
2765 IMFRateSupport *rate_support;
2766 IMFMediaEventGenerator *eg;
2767 IMFMediaSink *sink, *sink2;
2768 DWORD flags, count, id;
2769 IMFActivate *activate;
2770 IMFMediaEvent *event;
2771 ULONG refcount;
2772 IUnknown *unk;
2773 float rate;
2774 HRESULT hr;
2775 GUID guid;
2777 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2778 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2780 hr = MFCreateMediaType(&media_type);
2781 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2783 hr = MFCreateSampleGrabberSinkActivate(NULL, NULL, &activate);
2784 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2786 hr = MFCreateSampleGrabberSinkActivate(NULL, &grabber_callback, &activate);
2787 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2789 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2790 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2791 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2792 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2794 EXPECT_REF(media_type, 1);
2795 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
2796 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
2797 EXPECT_REF(media_type, 2);
2799 hr = IMFActivate_GetCount(activate, &count);
2800 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
2801 ok(!count, "Unexpected count %u.\n", count);
2803 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
2804 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
2806 check_interface(sink, &IID_IMFClockStateSink, TRUE);
2807 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
2808 check_interface(sink, &IID_IMFGetService, TRUE);
2809 check_interface(sink, &IID_IMFRateSupport, TRUE);
2810 check_service_interface(sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
2812 if (SUCCEEDED(MFGetService((IUnknown *)sink, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rate_support)))
2814 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
2815 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2816 ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
2818 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
2819 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2820 ok(rate == FLT_MAX, "Unexpected rate %f.\n", rate);
2822 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
2823 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2824 ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
2826 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
2827 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2828 ok(rate == -FLT_MAX, "Unexpected rate %f.\n", rate);
2830 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
2831 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2832 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2834 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
2835 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2836 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2838 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
2839 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2840 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2842 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
2843 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2844 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
2846 hr = IMFRateSupport_IsRateSupported(rate_support, TRUE, 1.0f, &rate);
2847 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2848 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
2850 IMFRateSupport_Release(rate_support);
2853 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2854 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2855 ok(flags & MEDIASINK_FIXED_STREAMS, "Unexpected flags %#x.\n", flags);
2857 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
2858 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
2859 ok(count == 1, "Unexpected stream count %u.\n", count);
2861 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream);
2862 ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
2864 check_interface(stream, &IID_IMFMediaEventGenerator, TRUE);
2865 check_interface(stream, &IID_IMFMediaTypeHandler, TRUE);
2867 hr = IMFStreamSink_GetIdentifier(stream, &id);
2868 ok(hr == S_OK, "Failed to get stream id, hr %#x.\n", hr);
2869 ok(id == 0, "Unexpected id %#x.\n", id);
2871 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
2872 ok(hr == S_OK, "Failed to get media sink, hr %x.\n", hr);
2873 ok(sink2 == sink, "Unexpected sink.\n");
2874 IMFMediaSink_Release(sink2);
2876 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 1, &stream2);
2877 ok(hr == MF_E_INVALIDINDEX, "Unexpected hr %#x.\n", hr);
2879 hr = IMFMediaSink_GetStreamSinkById(sink, 1, &stream2);
2880 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
2882 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
2883 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2885 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
2886 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2888 hr = IMFMediaSink_RemoveStreamSink(sink, 1);
2889 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
2891 check_interface(sink, &IID_IMFClockStateSink, TRUE);
2893 /* Event generator. */
2894 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFMediaEventGenerator, (void **)&eg);
2895 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
2897 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
2898 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2900 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&unk);
2901 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
2903 hr = IMFStreamSink_QueryInterface(stream, &IID_IMFMediaTypeHandler, (void **)&handler2);
2904 ok(hr == S_OK, "Failed to get handler interface, hr %#x.\n", hr);
2906 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2907 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2908 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2909 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2910 ok(count == 0, "Unexpected count %u.\n", count);
2911 ok(handler == handler2, "Unexpected handler.\n");
2913 IMFMediaTypeHandler_Release(handler);
2914 IMFMediaTypeHandler_Release(handler2);
2916 /* Set clock. */
2917 hr = MFCreatePresentationClock(&clock);
2918 ok(hr == S_OK, "Failed to create clock object, hr %#x.\n", hr);
2920 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
2921 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2923 hr = IMFMediaSink_GetPresentationClock(sink, &clock2);
2924 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
2926 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
2927 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2929 hr = IMFMediaSink_SetPresentationClock(sink, clock);
2930 ok(hr == S_OK, "Failed to set presentation clock, hr %#x.\n", hr);
2932 hr = MFCreateSystemTimeSource(&time_source);
2933 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2935 hr = IMFPresentationClock_SetTimeSource(clock, time_source);
2936 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
2937 IMFPresentationTimeSource_Release(time_source);
2939 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2940 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2942 hr = IMFActivate_ShutdownObject(activate);
2943 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2945 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
2946 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
2948 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
2949 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2951 /* On Win8+ this initialization happens automatically. */
2952 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
2953 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
2955 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
2956 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2958 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
2959 ok(hr == S_OK, "Failed to get media type count, hr %#x.\n", hr);
2960 ok(count == 0, "Unexpected count %u.\n", count);
2962 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
2963 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2964 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
2966 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
2967 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2968 ok(media_type2 == media_type, "Unexpected media type.\n");
2969 IMFMediaType_Release(media_type2);
2971 hr = MFCreateMediaType(&media_type2);
2972 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2974 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2975 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2977 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2978 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2980 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2981 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2983 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_Float);
2984 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2986 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2987 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
2989 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
2990 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2992 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
2993 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2995 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
2996 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
2997 IMFMediaType_Release(media_type);
2999 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3000 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3002 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
3003 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3004 ok(media_type2 == media_type, "Unexpected media type.\n");
3005 IMFMediaType_Release(media_type);
3007 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
3008 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3010 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, NULL);
3011 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3013 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
3014 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3016 hr = MFCreateMediaType(&media_type);
3017 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3019 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3020 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3022 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
3023 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3025 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
3026 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3028 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3029 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3031 media_type3 = (void *)0xdeadbeef;
3032 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
3033 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3034 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
3036 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1);
3037 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3039 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 1024);
3040 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3042 media_type3 = (void *)0xdeadbeef;
3043 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
3044 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3045 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
3047 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
3048 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3050 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
3051 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
3053 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
3054 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
3056 EXPECT_REF(clock, 3);
3057 hr = IMFMediaSink_Shutdown(sink);
3058 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3059 EXPECT_REF(clock, 1);
3061 hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event);
3062 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3064 hr = IMFMediaSink_Shutdown(sink);
3065 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3067 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3068 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3070 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream2);
3071 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3073 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
3074 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3076 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream2);
3077 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3079 hr = IMFStreamSink_GetEvent(stream, MF_EVENT_FLAG_NO_WAIT, &event);
3080 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3082 hr = IMFStreamSink_GetMediaSink(stream, &sink2);
3083 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3085 id = 1;
3086 hr = IMFStreamSink_GetIdentifier(stream, &id);
3087 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3088 ok(id == 1, "Unexpected id %u.\n", id);
3090 media_type3 = (void *)0xdeadbeef;
3091 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type3);
3092 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3093 ok(media_type3 == (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3);
3095 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
3096 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3098 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3099 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3101 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
3102 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3104 IMFMediaType_Release(media_type2);
3105 IMFMediaType_Release(media_type);
3107 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type);
3108 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3110 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
3111 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3113 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
3114 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3116 hr = IMFMediaTypeHandler_GetMajorType(handler, NULL);
3117 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3119 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3120 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3122 IMFMediaTypeHandler_Release(handler);
3124 handler = (void *)0xdeadbeef;
3125 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
3126 ok(hr == MF_E_STREAMSINK_REMOVED, "Unexpected hr %#x.\n", hr);
3127 ok(handler == (void *)0xdeadbeef, "Unexpected pointer.\n");
3129 hr = IMFStreamSink_GetMediaTypeHandler(stream, NULL);
3130 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3132 IMFMediaEventGenerator_Release(eg);
3133 IMFMediaSink_Release(sink);
3134 IMFStreamSink_Release(stream);
3136 refcount = IMFActivate_Release(activate);
3137 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3139 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
3140 hr = MFCreateMediaType(&media_type);
3141 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3143 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3144 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3145 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3146 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3148 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
3149 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
3151 hr = IMFActivate_SetUINT32(activate, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 1);
3152 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3154 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3155 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
3157 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3158 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
3159 ok(flags & MEDIASINK_RATELESS, "Unexpected flags %#x.\n", flags);
3161 hr = IMFActivate_ShutdownObject(activate);
3162 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3164 hr = IMFMediaSink_Shutdown(sink);
3165 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3167 IMFMediaSink_Release(sink);
3169 /* Detaching */
3170 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
3171 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
3173 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3174 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
3175 IMFMediaSink_Release(sink);
3177 hr = IMFActivate_ShutdownObject(activate);
3178 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3180 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3181 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3183 hr = IMFActivate_GetCount(activate, &count);
3184 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3186 hr = IMFActivate_DetachObject(activate);
3187 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3189 IMFActivate_Release(activate);
3191 IMFMediaType_Release(media_type);
3192 IMFPresentationClock_Release(clock);
3194 hr = MFShutdown();
3195 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3198 static void test_sample_grabber_is_mediatype_supported(void)
3200 IMFMediaType *media_type, *media_type2, *media_type3;
3201 IMFMediaTypeHandler *handler;
3202 IMFActivate *activate;
3203 IMFStreamSink *stream;
3204 IMFMediaSink *sink;
3205 ULONG refcount;
3206 HRESULT hr;
3207 GUID guid;
3209 /* IsMediaTypeSupported checks are done against the creation type, and check format data */
3210 hr = MFCreateMediaType(&media_type);
3211 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3213 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3214 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3215 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3216 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3217 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
3218 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3220 hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
3221 ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
3223 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
3224 ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
3226 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream);
3227 ok(hr == S_OK, "Failed to get sink stream, hr %#x.\n", hr);
3228 hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
3229 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3230 IMFStreamSink_Release(stream);
3232 IMFMediaSink_Release(sink);
3234 /* On Win8+ this initialization happens automatically. */
3235 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
3236 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3238 hr = MFCreateMediaType(&media_type2);
3239 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3241 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3242 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3243 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3244 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3245 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
3246 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3248 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
3249 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3251 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
3252 ok(hr == MF_E_INVALIDMEDIATYPE, "Failed to set media type, hr %#x.\n", hr);
3254 /* Make it match grabber type sample rate. */
3255 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
3256 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3258 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
3259 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3261 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type2);
3262 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3263 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type3);
3264 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
3265 ok(media_type3 == media_type2, "Unexpected media type instance.\n");
3266 IMFMediaType_Release(media_type3);
3268 /* Change original type. */
3269 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
3270 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3272 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
3273 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3275 hr = IMFMediaType_SetUINT32(media_type2, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000);
3276 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3278 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type2, NULL);
3279 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3281 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3282 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3283 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
3285 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3286 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3288 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3289 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3290 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
3292 IMFMediaType_Release(media_type2);
3293 IMFMediaType_Release(media_type);
3295 IMFMediaTypeHandler_Release(handler);
3297 refcount = IMFActivate_Release(activate);
3298 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3301 static BOOL is_supported_video_type(const GUID *guid)
3303 return IsEqualGUID(guid, &MFVideoFormat_L8)
3304 || IsEqualGUID(guid, &MFVideoFormat_L16)
3305 || IsEqualGUID(guid, &MFVideoFormat_D16)
3306 || IsEqualGUID(guid, &MFVideoFormat_IYUV)
3307 || IsEqualGUID(guid, &MFVideoFormat_YV12)
3308 || IsEqualGUID(guid, &MFVideoFormat_NV12)
3309 || IsEqualGUID(guid, &MFVideoFormat_420O)
3310 || IsEqualGUID(guid, &MFVideoFormat_P010)
3311 || IsEqualGUID(guid, &MFVideoFormat_P016)
3312 || IsEqualGUID(guid, &MFVideoFormat_UYVY)
3313 || IsEqualGUID(guid, &MFVideoFormat_YUY2)
3314 || IsEqualGUID(guid, &MFVideoFormat_P208)
3315 || IsEqualGUID(guid, &MFVideoFormat_NV11)
3316 || IsEqualGUID(guid, &MFVideoFormat_AYUV)
3317 || IsEqualGUID(guid, &MFVideoFormat_ARGB32)
3318 || IsEqualGUID(guid, &MFVideoFormat_RGB32)
3319 || IsEqualGUID(guid, &MFVideoFormat_A2R10G10B10)
3320 || IsEqualGUID(guid, &MFVideoFormat_A16B16G16R16F)
3321 || IsEqualGUID(guid, &MFVideoFormat_RGB24)
3322 || IsEqualGUID(guid, &MFVideoFormat_I420)
3323 || IsEqualGUID(guid, &MFVideoFormat_YVYU)
3324 || IsEqualGUID(guid, &MFVideoFormat_RGB555)
3325 || IsEqualGUID(guid, &MFVideoFormat_RGB565)
3326 || IsEqualGUID(guid, &MFVideoFormat_RGB8)
3327 || IsEqualGUID(guid, &MFVideoFormat_Y216)
3328 || IsEqualGUID(guid, &MFVideoFormat_v410)
3329 || IsEqualGUID(guid, &MFVideoFormat_Y41P)
3330 || IsEqualGUID(guid, &MFVideoFormat_Y41T)
3331 || IsEqualGUID(guid, &MFVideoFormat_Y42T)
3332 || IsEqualGUID(guid, &MFVideoFormat_ABGR32);
3335 static void test_video_processor(void)
3337 DWORD input_count, output_count, input_id, output_id, flags;
3338 DWORD input_min, input_max, output_min, output_max, i, count;
3339 IMFAttributes *attributes, *attributes2;
3340 IMFMediaType *media_type, *media_type2;
3341 MFT_OUTPUT_DATA_BUFFER output_buffer;
3342 MFT_OUTPUT_STREAM_INFO output_info;
3343 MFT_INPUT_STREAM_INFO input_info;
3344 IMFSample *sample, *sample2;
3345 IMFTransform *transform;
3346 IMFMediaBuffer *buffer;
3347 IMFMediaEvent *event;
3348 IUnknown *unk;
3349 HRESULT hr;
3350 GUID guid;
3352 hr = CoInitialize(NULL);
3353 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
3355 hr = CoCreateInstance(&CLSID_VideoProcessorMFT, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform,
3356 (void **)&transform);
3357 if (FAILED(hr))
3359 skip("Failed to create Video Processor instance, skipping tests.\n");
3360 goto failed;
3363 hr = IMFTransform_QueryInterface(transform, &IID_IMFMediaEventGenerator, (void **)&unk);
3364 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
3366 hr = IMFTransform_QueryInterface(transform, &IID_IMFShutdown, (void **)&unk);
3367 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
3369 /* Transform global attributes. */
3370 hr = IMFTransform_GetAttributes(transform, &attributes);
3371 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
3372 hr = IMFTransform_GetAttributes(transform, &attributes2);
3373 ok(hr == S_OK, "Failed to get attributes, hr %#x.\n", hr);
3374 ok(attributes == attributes2, "Unexpected instance.\n");
3375 IMFAttributes_Release(attributes);
3376 IMFAttributes_Release(attributes2);
3378 hr = IMFTransform_GetStreamLimits(transform, &input_min, &input_max, &output_min, &output_max);
3379 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
3380 ok(input_min == input_max && input_min == 1 && output_min == output_max && output_min == 1,
3381 "Unexpected stream limits.\n");
3383 hr = IMFTransform_GetStreamCount(transform, &input_count, &output_count);
3384 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
3385 ok(input_count == 1 && output_count == 1, "Unexpected stream count %u, %u.\n", input_count, output_count);
3387 hr = IMFTransform_GetStreamIDs(transform, 1, &input_id, 1, &output_id);
3388 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3390 input_id = 100;
3391 hr = IMFTransform_AddInputStreams(transform, 1, &input_id);
3392 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3394 hr = IMFTransform_DeleteInputStream(transform, 0);
3395 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3397 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
3398 todo_wine
3399 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3401 hr = IMFTransform_GetInputStreamAttributes(transform, 0, &attributes);
3402 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3404 hr = IMFTransform_GetOutputStatus(transform, &flags);
3405 todo_wine
3406 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3408 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes);
3409 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
3410 hr = IMFTransform_GetOutputStreamAttributes(transform, 0, &attributes2);
3411 ok(hr == S_OK, "Failed to get output attributes, hr %#x.\n", hr);
3412 ok(attributes == attributes2, "Unexpected instance.\n");
3413 IMFAttributes_Release(attributes);
3414 IMFAttributes_Release(attributes2);
3416 hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
3417 todo_wine
3418 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3420 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
3421 todo_wine
3422 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3424 hr = IMFTransform_GetInputCurrentType(transform, 1, &media_type);
3425 todo_wine
3426 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3428 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type);
3429 todo_wine
3430 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3432 hr = IMFTransform_GetOutputCurrentType(transform, 1, &media_type);
3433 todo_wine
3434 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3436 hr = IMFTransform_GetInputStreamInfo(transform, 1, &input_info);
3437 todo_wine
3438 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
3440 memset(&input_info, 0xcc, sizeof(input_info));
3441 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
3442 todo_wine {
3443 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3444 ok(input_info.dwFlags == 0, "Unexpected flag %#x.\n", input_info.dwFlags);
3445 ok(input_info.cbSize == 0, "Unexpected size %u.\n", input_info.cbSize);
3446 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
3447 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
3449 hr = MFCreateMediaEvent(MEUnknown, &GUID_NULL, S_OK, NULL, &event);
3450 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3451 hr = IMFTransform_ProcessEvent(transform, 0, event);
3452 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3453 hr = IMFTransform_ProcessEvent(transform, 1, event);
3454 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3455 IMFMediaEvent_Release(event);
3457 /* Configure stream types. */
3458 for (i = 0;;++i)
3460 if (FAILED(hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type)))
3462 todo_wine
3463 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3464 break;
3467 hr = IMFTransform_GetInputAvailableType(transform, 0, i, &media_type2);
3468 ok(hr == S_OK, "Failed to get available type, hr %#x.\n", hr);
3469 ok(media_type != media_type2, "Unexpected instance.\n");
3470 IMFMediaType_Release(media_type2);
3472 hr = IMFMediaType_GetMajorType(media_type, &guid);
3473 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3474 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
3476 hr = IMFMediaType_GetCount(media_type, &count);
3477 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
3478 ok(count == 2, "Unexpected count %u.\n", count);
3480 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
3481 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
3482 ok(is_supported_video_type(&guid), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid));
3484 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
3485 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
3487 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
3488 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
3490 hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type2);
3491 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
3493 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
3494 if (IsEqualGUID(&guid, &MFVideoFormat_L8) || IsEqualGUID(&guid, &MFVideoFormat_L16)
3495 || IsEqualGUID(&guid, &MFVideoFormat_D16) || IsEqualGUID(&guid, &MFVideoFormat_420O)
3496 || IsEqualGUID(&guid, &MFVideoFormat_A16B16G16R16F))
3498 IMFMediaType_Release(media_type);
3499 continue;
3502 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
3503 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3505 hr = IMFTransform_SetInputType(transform, 0, media_type, MFT_SET_TYPE_TEST_ONLY);
3506 ok(hr == S_OK, "Failed to test input type %s, hr %#x.\n", wine_dbgstr_guid(&guid), hr);
3508 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
3509 ok(hr == S_OK, "Failed to test input type, hr %#x.\n", hr);
3511 hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type2);
3512 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
3513 ok(media_type != media_type2, "Unexpected instance.\n");
3514 IMFMediaType_Release(media_type2);
3516 hr = IMFTransform_GetInputStatus(transform, 0, &flags);
3517 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
3518 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected input status %#x.\n", flags);
3520 hr = IMFTransform_GetInputStreamInfo(transform, 0, &input_info);
3521 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3522 ok(input_info.dwFlags == 0, "Unexpected flags %#x.\n", input_info.dwFlags);
3523 ok(input_info.cbMaxLookahead == 0, "Unexpected lookahead length %u.\n", input_info.cbMaxLookahead);
3524 ok(input_info.cbAlignment == 0, "Unexpected alignment %u.\n", input_info.cbAlignment);
3526 IMFMediaType_Release(media_type);
3529 /* IYUV -> RGB32 */
3530 hr = MFCreateMediaType(&media_type);
3531 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3533 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3534 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3536 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_IYUV);
3537 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3539 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)16 << 32) | 16);
3540 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3542 hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
3543 todo_wine
3544 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
3546 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
3547 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3549 hr = IMFTransform_SetOutputType(transform, 0, media_type, 0);
3550 todo_wine
3551 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
3553 memset(&output_info, 0, sizeof(output_info));
3554 hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
3555 todo_wine
3556 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
3557 ok(output_info.dwFlags == 0, "Unexpected flags %#x.\n", output_info.dwFlags);
3558 todo_wine
3559 ok(output_info.cbSize > 0, "Unexpected size %u.\n", output_info.cbSize);
3560 ok(output_info.cbAlignment == 0, "Unexpected alignment %u.\n", output_info.cbAlignment);
3562 hr = MFCreateSample(&sample);
3563 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
3565 hr = MFCreateSample(&sample2);
3566 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
3568 memset(&output_buffer, 0, sizeof(output_buffer));
3569 output_buffer.pSample = sample;
3570 flags = 0;
3571 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
3572 todo_wine
3573 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
3574 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
3575 ok(flags == 0, "Unexpected status %#x.\n", flags);
3577 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
3578 todo_wine
3579 ok(hr == S_OK, "Failed to push a sample, hr %#x.\n", hr);
3581 hr = IMFTransform_ProcessInput(transform, 0, sample2, 0);
3582 todo_wine
3583 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
3585 memset(&output_buffer, 0, sizeof(output_buffer));
3586 output_buffer.pSample = sample;
3587 flags = 0;
3588 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
3589 todo_wine
3590 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
3591 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
3592 ok(flags == 0, "Unexpected status %#x.\n", flags);
3594 hr = IMFSample_SetSampleTime(sample2, 0);
3595 ok(hr == S_OK, "Failed to set sample time, hr %#x.\n", hr);
3596 memset(&output_buffer, 0, sizeof(output_buffer));
3597 output_buffer.pSample = sample;
3598 flags = 0;
3599 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
3600 todo_wine
3601 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3602 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
3603 ok(flags == 0, "Unexpected status %#x.\n", flags);
3605 hr = MFCreateMemoryBuffer(1024 * 1024, &buffer);
3606 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
3608 hr = IMFSample_AddBuffer(sample2, buffer);
3609 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
3611 hr = IMFSample_AddBuffer(sample, buffer);
3612 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
3614 memset(&output_buffer, 0, sizeof(output_buffer));
3615 output_buffer.pSample = sample;
3616 flags = 0;
3617 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
3618 todo_wine
3619 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr);
3620 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
3621 ok(flags == 0, "Unexpected status %#x.\n", flags);
3623 if (SUCCEEDED(hr))
3625 memset(&output_buffer, 0, sizeof(output_buffer));
3626 output_buffer.pSample = sample;
3627 flags = 0;
3628 hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &flags);
3629 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Unexpected hr %#x.\n", hr);
3630 ok(output_buffer.dwStatus == 0, "Unexpected buffer status, %#x.\n", output_buffer.dwStatus);
3631 ok(flags == 0, "Unexpected status %#x.\n", flags);
3634 IMFSample_Release(sample2);
3635 IMFSample_Release(sample);
3636 IMFMediaBuffer_Release(buffer);
3638 IMFMediaType_Release(media_type);
3640 IMFTransform_Release(transform);
3642 failed:
3643 CoUninitialize();
3646 static void test_quality_manager(void)
3648 IMFQualityManager *manager;
3649 HRESULT hr;
3651 hr = MFCreateStandardQualityManager(&manager);
3652 ok(hr == S_OK, "Failed to create quality manager, hr %#x.\n", hr);
3654 hr = IMFQualityManager_NotifyPresentationClock(manager, NULL);
3655 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3657 IMFQualityManager_Release(manager);
3660 static void test_sar(void)
3662 IMFPresentationClock *present_clock, *present_clock2;
3663 IMFMediaType *mediatype, *mediatype2, *mediatype3;
3664 IMFClockStateSink *state_sink, *state_sink2;
3665 IMFMediaTypeHandler *handler, *handler2;
3666 IMFPresentationTimeSource *time_source;
3667 IMFSimpleAudioVolume *simple_volume;
3668 IMFAudioStreamVolume *stream_volume;
3669 IMFMediaSink *sink, *sink2;
3670 IMFStreamSink *stream_sink;
3671 IMFAttributes *attributes;
3672 DWORD i, id, flags, count;
3673 IMFActivate *activate;
3674 MFCLOCK_STATE state;
3675 IMFClock *clock;
3676 IUnknown *unk;
3677 HRESULT hr;
3678 GUID guid;
3679 BOOL mute;
3680 int found;
3682 hr = CoInitialize(NULL);
3683 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
3685 hr = MFCreateAudioRenderer(NULL, &sink);
3686 if (hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE)
3688 skip("No audio playback device available.\n");
3689 CoUninitialize();
3690 return;
3692 ok(hr == S_OK, "Failed to create renderer, hr %#x.\n", hr);
3694 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3695 ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
3697 hr = MFCreatePresentationClock(&present_clock);
3698 ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr);
3700 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFPresentationTimeSource, (void **)&time_source);
3701 todo_wine
3702 ok(hr == S_OK, "Failed to get time source interface, hr %#x.\n", hr);
3704 if (SUCCEEDED(hr))
3706 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&state_sink2);
3707 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3708 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&state_sink);
3709 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3710 ok(state_sink == state_sink2, "Unexpected clock sink.\n");
3711 IMFClockStateSink_Release(state_sink2);
3712 IMFClockStateSink_Release(state_sink);
3714 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3715 ok(hr == MF_E_NO_CLOCK, "Unexpected hr %#x.\n", hr);
3717 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &flags);
3718 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
3719 ok(flags == MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ, "Unexpected flags %#x.\n", flags);
3721 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3722 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
3723 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3725 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&state_sink);
3726 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
3728 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3729 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3731 IMFClockStateSink_Release(state_sink);
3733 IMFPresentationTimeSource_Release(time_source);
3735 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
3736 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
3738 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
3739 ok(hr == MF_E_STREAMSINKS_FIXED, "Unexpected hr %#x.\n", hr);
3741 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
3742 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3744 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
3745 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3746 ok(count == 1, "Unexpected count %u.\n", count);
3748 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3749 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3750 ok(flags == (MEDIASINK_FIXED_STREAMS | MEDIASINK_CAN_PREROLL), "Unexpected flags %#x.\n", flags);
3752 check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
3753 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
3754 check_interface(sink, &IID_IMFClockStateSink, TRUE);
3755 check_interface(sink, &IID_IMFGetService, TRUE);
3756 todo_wine check_interface(sink, &IID_IMFPresentationTimeSource, TRUE);
3757 check_service_interface(sink, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, TRUE);
3759 /* Clock */
3760 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&state_sink);
3761 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3763 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3764 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3766 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3767 ok(hr == MF_E_INVALID_STATE_TRANSITION, "Unexpected hr %#x.\n", hr);
3769 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3770 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3772 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3773 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3775 IMFClockStateSink_Release(state_sink);
3777 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
3778 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3780 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3781 todo_wine
3782 ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr);
3784 hr = MFCreateSystemTimeSource(&time_source);
3785 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3787 hr = IMFPresentationClock_SetTimeSource(present_clock, time_source);
3788 ok(hr == S_OK, "Failed to set time source, hr %#x.\n", hr);
3789 IMFPresentationTimeSource_Release(time_source);
3791 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3792 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3794 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
3795 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3797 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
3798 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3799 ok(present_clock == present_clock2, "Unexpected instance.\n");
3800 IMFPresentationClock_Release(present_clock2);
3802 /* Stream */
3803 hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
3804 ok(hr == S_OK, "Failed to get a stream, hr %#x.\n", hr);
3806 check_interface(stream_sink, &IID_IMFMediaEventGenerator, TRUE);
3807 check_interface(stream_sink, &IID_IMFMediaTypeHandler, TRUE);
3808 todo_wine check_interface(stream_sink, &IID_IMFGetService, TRUE);
3810 hr = IMFStreamSink_GetIdentifier(stream_sink, &id);
3811 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3812 ok(!id, "Unexpected id.\n");
3814 hr = IMFStreamSink_GetMediaSink(stream_sink, &sink2);
3815 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3816 ok(sink == sink2, "Unexpected object.\n");
3817 IMFMediaSink_Release(sink2);
3819 hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &handler);
3820 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3822 hr = IMFStreamSink_QueryInterface(stream_sink, &IID_IMFMediaTypeHandler, (void **)&handler2);
3823 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3824 ok(handler2 == handler, "Unexpected instance.\n");
3825 IMFMediaTypeHandler_Release(handler2);
3827 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
3828 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3829 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
3831 count = 0;
3832 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
3833 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3834 ok(!!count, "Unexpected type count %u.\n", count);
3836 /* A number of same major/subtype entries are returned, with different degrees of finer format
3837 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
3839 for (i = 0, found = -1; i < count; ++i)
3841 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, i, &mediatype);
3842 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3844 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL)))
3845 found = i;
3846 IMFMediaType_Release(mediatype);
3848 if (found != -1) break;
3850 ok(found != -1, "Haven't found a supported type.\n");
3852 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &mediatype);
3853 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3855 hr = MFCreateMediaType(&mediatype);
3856 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3858 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
3859 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3860 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
3862 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3863 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3864 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3865 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3867 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3868 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3869 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype, NULL);
3870 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3872 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype);
3873 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3875 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, found, &mediatype2);
3876 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3878 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, found, &mediatype3);
3879 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3880 ok(mediatype2 == mediatype3, "Unexpected instance.\n");
3881 IMFMediaType_Release(mediatype3);
3883 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, mediatype2, NULL);
3884 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3886 IMFMediaType_Release(mediatype);
3888 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype2);
3889 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3891 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &mediatype);
3892 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3893 ok(mediatype == mediatype2, "Unexpected instance.\n");
3894 IMFMediaType_Release(mediatype);
3896 IMFMediaType_Release(mediatype2);
3898 /* Reset back to uninitialized state. */
3899 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
3900 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3902 IMFMediaTypeHandler_Release(handler);
3904 /* State change with initialized stream. */
3905 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFClockStateSink, (void **)&state_sink);
3906 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3908 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3909 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3911 hr = IMFClockStateSink_OnClockStart(state_sink, 0, 0);
3912 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3914 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3915 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3917 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3918 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3920 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3921 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3923 hr = IMFClockStateSink_OnClockPause(state_sink, 0);
3924 ok(hr == MF_E_INVALID_STATE_TRANSITION, "Unexpected hr %#x.\n", hr);
3926 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3927 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3929 hr = IMFClockStateSink_OnClockRestart(state_sink, 0);
3930 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3932 hr = IMFClockStateSink_OnClockStop(state_sink, 0);
3933 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3935 IMFClockStateSink_Release(state_sink);
3937 IMFStreamSink_Release(stream_sink);
3939 /* Volume control */
3940 hr = MFGetService((IUnknown *)sink, &MR_POLICY_VOLUME_SERVICE, &IID_IMFSimpleAudioVolume, (void **)&simple_volume);
3941 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3943 hr = IMFSimpleAudioVolume_GetMute(simple_volume, &mute);
3944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3946 IMFSimpleAudioVolume_Release(simple_volume);
3948 hr = MFGetService((IUnknown *)sink, &MR_STREAM_VOLUME_SERVICE, &IID_IMFAudioStreamVolume, (void **)&stream_volume);
3949 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3951 hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, &count);
3952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3954 hr = IMFAudioStreamVolume_GetChannelCount(stream_volume, NULL);
3955 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3957 IMFAudioStreamVolume_Release(stream_volume);
3959 hr = MFGetService((IUnknown *)sink, &MR_AUDIO_POLICY_SERVICE, &IID_IMFAudioPolicy, (void **)&unk);
3960 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
3961 IUnknown_Release(unk);
3963 /* Shutdown */
3964 EXPECT_REF(present_clock, 2);
3965 hr = IMFMediaSink_Shutdown(sink);
3966 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3967 EXPECT_REF(present_clock, 1);
3969 hr = IMFMediaSink_Shutdown(sink);
3970 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3972 hr = IMFMediaSink_AddStreamSink(sink, 123, NULL, &stream_sink);
3973 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3975 hr = IMFMediaSink_RemoveStreamSink(sink, 0);
3976 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3978 hr = IMFMediaSink_GetStreamSinkCount(sink, NULL);
3979 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3981 hr = IMFMediaSink_GetStreamSinkCount(sink, &count);
3982 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3984 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
3985 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3987 hr = IMFMediaSink_SetPresentationClock(sink, NULL);
3988 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3990 hr = IMFMediaSink_SetPresentationClock(sink, present_clock);
3991 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3993 hr = IMFMediaSink_GetPresentationClock(sink, NULL);
3994 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3996 hr = IMFMediaSink_GetPresentationClock(sink, &present_clock2);
3997 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3999 IMFMediaSink_Release(sink);
4001 /* Activation */
4002 hr = MFCreateAudioRendererActivate(&activate);
4003 ok(hr == S_OK, "Failed to create activation object, hr %#x.\n", hr);
4005 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
4006 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4008 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
4009 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4010 ok(sink == sink2, "Unexpected instance.\n");
4011 IMFMediaSink_Release(sink2);
4013 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4014 ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
4016 hr = IMFActivate_ShutdownObject(activate);
4017 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4019 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4020 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
4022 IMFMediaSink_Release(sink);
4024 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
4025 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4027 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4028 todo_wine
4029 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
4031 IMFMediaSink_Release(sink);
4033 hr = IMFActivate_DetachObject(activate);
4034 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4036 IMFActivate_Release(activate);
4038 IMFPresentationClock_Release(present_clock);
4040 hr = MFShutdown();
4041 ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
4043 /* SAR attributes */
4044 hr = MFCreateAttributes(&attributes, 0);
4045 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
4047 /* Specify role. */
4048 hr = IMFAttributes_SetUINT32(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, eMultimedia);
4049 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4051 hr = MFCreateAudioRenderer(attributes, &sink);
4052 ok(hr == S_OK, "Failed to create a sink, hr %#x.\n", hr);
4053 IMFMediaSink_Release(sink);
4055 /* Invalid endpoint. */
4056 hr = IMFAttributes_SetString(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, L"endpoint");
4057 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4059 hr = MFCreateAudioRenderer(attributes, &sink);
4060 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4062 hr = IMFAttributes_DeleteItem(attributes, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE);
4063 ok(hr == S_OK, "Failed to remove attribute, hr %#x.\n", hr);
4065 hr = MFCreateAudioRenderer(attributes, &sink);
4066 ok(hr == MF_E_NO_AUDIO_PLAYBACK_DEVICE, "Failed to create a sink, hr %#x.\n", hr);
4068 CoUninitialize();
4071 static void test_evr(void)
4073 IMFVideoSampleAllocatorCallback *allocator_callback;
4074 IMFStreamSink *stream_sink, *stream_sink2;
4075 IMFVideoDisplayControl *display_control;
4076 IMFMediaType *media_type, *media_type2;
4077 IMFVideoSampleAllocator *allocator;
4078 IMFMediaTypeHandler *type_handler;
4079 IMFVideoRenderer *video_renderer;
4080 IMFMediaSink *sink, *sink2;
4081 IMFAttributes *attributes;
4082 DWORD flags, count, value;
4083 IMFActivate *activate;
4084 HWND window, window2;
4085 LONG sample_count;
4086 IMFGetService *gs;
4087 IMFSample *sample;
4088 IUnknown *unk;
4089 UINT64 window3;
4090 HRESULT hr;
4091 GUID guid;
4093 hr = CoInitialize(NULL);
4094 ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
4096 hr = MFCreateVideoRenderer(&IID_IMFVideoRenderer, (void **)&video_renderer);
4097 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4099 hr = IMFVideoRenderer_InitializeRenderer(video_renderer, NULL, NULL);
4100 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4102 IMFVideoRenderer_Release(video_renderer);
4104 hr = MFCreateVideoRendererActivate(NULL, NULL);
4105 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4107 /* Window */
4108 window = create_window();
4109 hr = MFCreateVideoRendererActivate(window, &activate);
4110 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
4112 hr = IMFActivate_GetUINT64(activate, &MF_ACTIVATE_VIDEO_WINDOW, &window3);
4113 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
4114 ok(UlongToHandle(window3) == window, "Unexpected value.\n");
4116 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
4117 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4119 check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
4120 check_interface(sink, &IID_IMFVideoRenderer, TRUE);
4121 check_interface(sink, &IID_IMFMediaEventGenerator, TRUE);
4122 check_interface(sink, &IID_IMFClockStateSink, TRUE);
4123 check_interface(sink, &IID_IMFGetService, TRUE);
4124 check_interface(sink, &IID_IMFQualityAdvise, TRUE);
4126 hr = MFGetService((IUnknown *)sink, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl,
4127 (void **)&display_control);
4128 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4130 window2 = NULL;
4131 hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window2);
4132 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4133 ok(window2 == window, "Unexpected window %p.\n", window2);
4135 IMFVideoDisplayControl_Release(display_control);
4136 IMFMediaSink_Release(sink);
4137 IMFActivate_Release(activate);
4138 DestroyWindow(window);
4140 hr = MFCreateVideoRendererActivate(NULL, &activate);
4141 ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
4143 hr = IMFActivate_GetCount(activate, &count);
4144 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
4145 ok(count == 1, "Unexpected count %u.\n", count);
4147 hr = IMFActivate_GetUINT64(activate, &MF_ACTIVATE_VIDEO_WINDOW, &window3);
4148 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
4149 ok(!window3, "Unexpected value.\n");
4151 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
4152 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4154 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFAttributes, (void **)&attributes);
4155 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4156 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFMediaSink, (void **)&unk);
4157 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4158 IUnknown_Release(unk);
4159 hr = IMFAttributes_GetCount(attributes, &count);
4160 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4161 ok(!!count, "Unexpected count %u.\n", count);
4162 /* Rendering preferences are not immediately propagated to the presenter. */
4163 hr = IMFAttributes_SetUINT32(attributes, &EVRConfig_ForceBob, 1);
4164 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4165 hr = MFGetService((IUnknown *)sink, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control);
4166 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4167 hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags);
4168 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4169 ok(!flags, "Unexpected flags %#x.\n", flags);
4170 IMFVideoDisplayControl_Release(display_control);
4171 IMFAttributes_Release(attributes);
4173 /* Primary stream type handler. */
4174 hr = IMFMediaSink_GetStreamSinkById(sink, 0, &stream_sink);
4175 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4177 hr = IMFStreamSink_QueryInterface(stream_sink, &IID_IMFAttributes, (void **)&attributes);
4178 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4179 hr = IMFAttributes_GetCount(attributes, &count);
4180 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4181 ok(count == 2, "Unexpected count %u.\n", count);
4182 value = 0;
4183 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, &value);
4184 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4185 ok(value == 1, "Unexpected attribute value %u.\n", value);
4186 value = 0;
4187 hr = IMFAttributes_GetUINT32(attributes, &MF_SA_D3D_AWARE, &value);
4188 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4189 ok(value == 1, "Unexpected attribute value %u.\n", value);
4191 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFStreamSink, (void **)&unk);
4192 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4193 IUnknown_Release(unk);
4194 IMFAttributes_Release(attributes);
4196 hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, &type_handler);
4197 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4199 hr = IMFMediaTypeHandler_GetMajorType(type_handler, NULL);
4200 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4202 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &guid);
4203 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4204 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected type %s.\n", wine_dbgstr_guid(&guid));
4206 /* Supported types are not advertised. */
4207 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, NULL);
4208 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4210 count = 1;
4211 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4212 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4213 ok(!count, "Unexpected count %u.\n", count);
4215 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, NULL);
4216 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
4218 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 0, &media_type);
4219 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
4221 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, NULL);
4222 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4224 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4225 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4227 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4228 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4230 hr = MFCreateMediaType(&media_type);
4231 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4233 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4234 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4236 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
4237 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4239 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
4240 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4242 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4243 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4245 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4246 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
4248 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
4249 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4251 media_type2 = (void *)0x1;
4252 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4253 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4254 ok(!media_type2, "Unexpected media type %p.\n", media_type2);
4256 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4257 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4259 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type2);
4260 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4261 hr = IMFMediaType_QueryInterface(media_type2, &IID_IMFVideoMediaType, (void **)&unk);
4262 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4263 IUnknown_Release(unk);
4264 IMFMediaType_Release(media_type2);
4266 IMFMediaType_Release(media_type);
4268 IMFMediaTypeHandler_Release(type_handler);
4270 /* Stream uses an allocator. */
4271 hr = MFGetService((IUnknown *)stream_sink, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator,
4272 (void **)&allocator);
4273 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4275 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_callback);
4276 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4278 sample_count = 0;
4279 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback, &sample_count);
4280 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4281 ok(!sample_count, "Unexpected sample count %d.\n", sample_count);
4283 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
4284 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4286 IMFVideoSampleAllocatorCallback_Release(allocator_callback);
4287 IMFVideoSampleAllocator_Release(allocator);
4289 /* Same test for a substream. */
4290 hr = IMFMediaSink_AddStreamSink(sink, 1, NULL, &stream_sink2);
4291 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4293 hr = MFGetService((IUnknown *)stream_sink2, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IMFVideoSampleAllocator,
4294 (void **)&allocator);
4295 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4296 IMFVideoSampleAllocator_Release(allocator);
4298 hr = IMFMediaSink_RemoveStreamSink(sink, 1);
4299 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4301 IMFStreamSink_Release(stream_sink2);
4303 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4304 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4305 ok(flags == (MEDIASINK_CAN_PREROLL | MEDIASINK_CLOCK_REQUIRED), "Unexpected flags %#x.\n", flags);
4307 hr = IMFMediaSink_QueryInterface(sink, &IID_IMFGetService, (void **)&gs);
4308 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4310 hr = IMFGetService_GetService(gs, &MR_VIDEO_MIXER_SERVICE, &IID_IMFVideoMixerControl, (void **)&unk);
4311 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4312 IUnknown_Release(unk);
4314 IMFGetService_Release(gs);
4316 hr = IMFActivate_ShutdownObject(activate);
4317 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4319 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4320 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
4322 /* Activate again. */
4323 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
4324 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4325 todo_wine
4326 ok(sink == sink2, "Unexpected instance.\n");
4327 IMFMediaSink_Release(sink2);
4329 hr = IMFActivate_DetachObject(activate);
4330 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4332 hr = IMFMediaSink_GetCharacteristics(sink, &flags);
4333 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
4335 hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
4336 ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
4338 hr = IMFActivate_ShutdownObject(activate);
4339 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4341 IMFMediaSink_Release(sink2);
4342 IMFMediaSink_Release(sink);
4344 IMFActivate_Release(activate);
4346 CoUninitialize();
4349 static void test_MFCreateSimpleTypeHandler(void)
4351 IMFMediaType *media_type, *media_type2, *media_type3;
4352 IMFMediaTypeHandler *handler;
4353 DWORD count;
4354 HRESULT hr;
4355 GUID guid;
4357 hr = MFCreateSimpleTypeHandler(&handler);
4358 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4360 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, NULL);
4361 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4363 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
4364 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
4366 count = 0;
4367 hr = IMFMediaTypeHandler_GetMediaTypeCount(handler, &count);
4368 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
4369 ok(count == 1, "Unexpected count %u.\n", count);
4371 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, NULL);
4372 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4374 media_type = (void *)0xdeadbeef;
4375 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
4376 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4377 ok(!media_type, "Unexpected pointer.\n");
4379 hr = MFCreateMediaType(&media_type);
4380 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4382 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
4383 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
4385 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, media_type);
4386 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
4388 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 0, &media_type2);
4389 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4390 ok(media_type2 == media_type, "Unexpected type.\n");
4391 IMFMediaType_Release(media_type2);
4393 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, NULL, NULL);
4394 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4396 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, NULL);
4397 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4399 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type, &media_type2);
4400 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4402 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(handler, 1, &media_type2);
4403 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
4405 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type2);
4406 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4407 ok(media_type == media_type2, "Unexpected pointer.\n");
4408 IMFMediaType_Release(media_type2);
4410 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
4411 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4413 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4414 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4416 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
4417 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4418 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4420 hr = MFCreateMediaType(&media_type3);
4421 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4423 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, NULL);
4424 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4426 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4427 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4429 /* Different major types. */
4430 media_type2 = (void *)0xdeadbeef;
4431 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4432 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4433 ok(!media_type2, "Unexpected pointer.\n");
4435 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4436 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4438 media_type2 = (void *)0xdeadbeef;
4439 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4440 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4441 ok(!media_type2, "Unexpected pointer.\n");
4443 /* Handler missing subtype. */
4444 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4445 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4447 media_type2 = (void *)0xdeadbeef;
4448 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4449 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4450 ok(!media_type2, "Unexpected pointer.\n");
4452 /* Different subtypes. */
4453 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
4454 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4456 media_type2 = (void *)0xdeadbeef;
4457 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4458 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4459 ok(!media_type2, "Unexpected pointer.\n");
4461 /* Same major/subtype. */
4462 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB24);
4463 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4465 media_type2 = (void *)0xdeadbeef;
4466 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4467 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4468 ok(!media_type2, "Unexpected pointer.\n");
4470 /* Set one more attribute. */
4471 hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)4 << 32 | 4);
4472 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4474 media_type2 = (void *)0xdeadbeef;
4475 hr = IMFMediaTypeHandler_IsMediaTypeSupported(handler, media_type3, &media_type2);
4476 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4477 ok(!media_type2, "Unexpected pointer.\n");
4479 IMFMediaType_Release(media_type3);
4480 IMFMediaType_Release(media_type);
4482 hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, NULL);
4483 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
4485 media_type = (void *)0xdeadbeef;
4486 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
4487 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4488 ok(!media_type, "Unexpected pointer.\n");
4490 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
4491 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4493 IMFMediaTypeHandler_Release(handler);
4496 static void test_MFGetSupportedMimeTypes(void)
4498 PROPVARIANT value;
4499 HRESULT hr;
4501 hr = MFGetSupportedMimeTypes(NULL);
4502 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4504 value.vt = VT_EMPTY;
4505 hr = MFGetSupportedMimeTypes(&value);
4506 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4507 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
4509 PropVariantClear(&value);
4512 static void test_MFGetSupportedSchemes(void)
4514 PROPVARIANT value;
4515 HRESULT hr;
4517 hr = MFGetSupportedSchemes(NULL);
4518 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4520 value.vt = VT_EMPTY;
4521 hr = MFGetSupportedSchemes(&value);
4522 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4523 ok(value.vt == (VT_VECTOR | VT_LPWSTR), "Unexpected value type %#x.\n", value.vt);
4525 PropVariantClear(&value);
4528 static BOOL is_sample_copier_available_type(IMFMediaType *type)
4530 GUID major = { 0 };
4531 UINT32 count;
4532 HRESULT hr;
4534 hr = IMFMediaType_GetMajorType(type, &major);
4535 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4537 hr = IMFMediaType_GetCount(type, &count);
4538 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
4539 ok(count == 1, "Unexpected attribute count %u.\n", count);
4541 return IsEqualGUID(&major, &MFMediaType_Video) || IsEqualGUID(&major, &MFMediaType_Audio);
4544 static void test_sample_copier(void)
4546 IMFAttributes *attributes, *attributes2;
4547 DWORD in_min, in_max, out_min, out_max;
4548 IMFMediaType *mediatype, *mediatype2;
4549 MFT_OUTPUT_STREAM_INFO output_info;
4550 IMFSample *sample, *client_sample;
4551 MFT_INPUT_STREAM_INFO input_info;
4552 DWORD input_count, output_count;
4553 MFT_OUTPUT_DATA_BUFFER buffer;
4554 IMFMediaBuffer *media_buffer;
4555 DWORD count, flags, status;
4556 IMFTransform *copier;
4557 UINT32 value;
4558 HRESULT hr;
4560 hr = MFCreateSampleCopierMFT(&copier);
4561 ok(hr == S_OK, "Failed to create sample copier, hr %#x.\n", hr);
4563 hr = IMFTransform_GetAttributes(copier, &attributes);
4564 ok(hr == S_OK, "Failed to get transform attributes, hr %#x.\n", hr);
4565 hr = IMFTransform_GetAttributes(copier, &attributes2);
4566 ok(hr == S_OK, "Failed to get transform attributes, hr %#x.\n", hr);
4567 ok(attributes == attributes2, "Unexpected instance.\n");
4568 IMFAttributes_Release(attributes2);
4569 hr = IMFAttributes_GetCount(attributes, &count);
4570 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4571 ok(count == 1, "Unexpected attribute count %u.\n", count);
4572 hr = IMFAttributes_GetUINT32(attributes, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, &value);
4573 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4574 ok(!!value, "Unexpected value %u.\n", value);
4575 IMFAttributes_Release(attributes);
4577 hr = IMFTransform_GetInputStreamAttributes(copier, 0, &attributes);
4578 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4580 hr = IMFTransform_GetInputStreamAttributes(copier, 1, &attributes);
4581 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4583 hr = IMFTransform_GetOutputStreamAttributes(copier, 0, &attributes);
4584 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4586 hr = IMFTransform_GetOutputStreamAttributes(copier, 1, &attributes);
4587 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4589 hr = IMFTransform_SetOutputBounds(copier, 0, 0);
4590 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4592 /* No dynamic streams. */
4593 input_count = output_count = 0;
4594 hr = IMFTransform_GetStreamCount(copier, &input_count, &output_count);
4595 ok(hr == S_OK, "Failed to get stream count, hr %#x.\n", hr);
4596 ok(input_count == 1 && output_count == 1, "Unexpected streams count.\n");
4598 hr = IMFTransform_GetStreamLimits(copier, &in_min, &in_max, &out_min, &out_max);
4599 ok(hr == S_OK, "Failed to get stream limits, hr %#x.\n", hr);
4600 ok(in_min == in_max && in_min == 1 && out_min == out_max && out_min == 1, "Unexpected stream limits.\n");
4602 hr = IMFTransform_GetStreamIDs(copier, 1, &input_count, 1, &output_count);
4603 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4605 hr = IMFTransform_DeleteInputStream(copier, 0);
4606 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4608 /* Available types. */
4609 hr = IMFTransform_GetInputAvailableType(copier, 0, 0, &mediatype);
4610 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4611 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
4612 IMFMediaType_Release(mediatype);
4614 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype);
4615 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4616 ok(is_sample_copier_available_type(mediatype), "Unexpected type.\n");
4617 IMFMediaType_Release(mediatype);
4619 hr = IMFTransform_GetInputAvailableType(copier, 0, 2, &mediatype);
4620 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
4622 hr = IMFTransform_GetInputAvailableType(copier, 1, 0, &mediatype);
4623 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
4625 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype);
4626 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
4628 hr = IMFTransform_GetOutputAvailableType(copier, 1, 0, &mediatype);
4629 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
4631 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype);
4632 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4634 hr = IMFTransform_GetInputCurrentType(copier, 1, &mediatype);
4635 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
4637 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype);
4638 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4640 hr = IMFTransform_GetOutputCurrentType(copier, 1, &mediatype);
4641 ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr);
4643 hr = MFCreateSample(&sample);
4644 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4646 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4647 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4649 hr = MFCreateMediaType(&mediatype);
4650 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4652 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
4653 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4655 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4656 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4658 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4659 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4661 hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16);
4662 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4664 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4665 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
4666 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
4667 ok(!output_info.cbSize, "Unexpected size %u.\n", output_info.cbSize);
4668 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
4670 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
4671 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
4673 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
4674 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
4675 ok(!input_info.cbSize, "Unexpected size %u.\n", input_info.cbSize);
4676 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
4677 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
4679 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
4680 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4682 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4683 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
4684 ok(!output_info.dwFlags, "Unexpected flags %#x.\n", output_info.dwFlags);
4685 ok(output_info.cbSize == 16 * 16, "Unexpected size %u.\n", output_info.cbSize);
4686 ok(!output_info.cbAlignment, "Unexpected alignment %u.\n", output_info.cbAlignment);
4688 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
4689 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
4690 IMFMediaType_Release(mediatype2);
4692 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
4693 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4695 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
4696 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4698 /* Setting input type resets output type. */
4699 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
4700 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4701 IMFMediaType_Release(mediatype2);
4703 hr = IMFTransform_SetInputType(copier, 0, mediatype, 0);
4704 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4706 hr = IMFTransform_GetOutputCurrentType(copier, 0, &mediatype2);
4707 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4709 hr = IMFTransform_GetInputAvailableType(copier, 0, 1, &mediatype2);
4710 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4711 ok(is_sample_copier_available_type(mediatype2), "Unexpected type.\n");
4712 IMFMediaType_Release(mediatype2);
4714 hr = IMFTransform_GetInputStreamInfo(copier, 0, &input_info);
4715 ok(hr == S_OK, "Failed to get stream info, hr %#x.\n", hr);
4716 ok(!input_info.hnsMaxLatency, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info.hnsMaxLatency));
4717 ok(!input_info.dwFlags, "Unexpected flags %#x.\n", input_info.dwFlags);
4718 ok(input_info.cbSize == 16 * 16, "Unexpected size %u.\n", input_info.cbSize);
4719 ok(!input_info.cbMaxLookahead, "Unexpected lookahead size %u.\n", input_info.cbMaxLookahead);
4720 ok(!input_info.cbAlignment, "Unexpected alignment %u.\n", input_info.cbAlignment);
4722 hr = IMFTransform_GetOutputAvailableType(copier, 0, 0, &mediatype2);
4723 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4724 hr = IMFMediaType_IsEqual(mediatype2, mediatype, &flags);
4725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4726 IMFMediaType_Release(mediatype2);
4728 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
4729 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
4730 ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Unexpected flags %#x.\n", flags);
4732 hr = IMFTransform_GetInputCurrentType(copier, 0, &mediatype2);
4733 ok(hr == S_OK, "Failed to get current type, hr %#x.\n", hr);
4734 IMFMediaType_Release(mediatype2);
4736 hr = IMFTransform_GetOutputStatus(copier, &flags);
4737 ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
4739 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
4740 ok(hr == S_OK, "Failed to set output type, hr %#x.\n", hr);
4742 hr = IMFTransform_GetOutputStatus(copier, &flags);
4743 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
4744 ok(!flags, "Unexpected flags %#x.\n", flags);
4746 /* Pushing samples. */
4747 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
4748 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4750 hr = IMFSample_AddBuffer(sample, media_buffer);
4751 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
4752 IMFMediaBuffer_Release(media_buffer);
4754 EXPECT_REF(sample, 1);
4755 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4756 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4757 EXPECT_REF(sample, 2);
4759 hr = IMFTransform_GetInputStatus(copier, 0, &flags);
4760 ok(hr == S_OK, "Failed to get input status, hr %#x.\n", hr);
4761 ok(!flags, "Unexpected flags %#x.\n", flags);
4763 hr = IMFTransform_GetOutputStatus(copier, &flags);
4764 ok(hr == S_OK, "Failed to get output status, hr %#x.\n", hr);
4765 ok(flags == MFT_OUTPUT_STATUS_SAMPLE_READY, "Unexpected flags %#x.\n", flags);
4767 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4768 ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr);
4770 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4771 ok(hr == S_OK, "Failed to get output info, hr %#x.\n", hr);
4773 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &media_buffer);
4774 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4776 hr = MFCreateSample(&client_sample);
4777 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4779 hr = IMFSample_AddBuffer(client_sample, media_buffer);
4780 ok(hr == S_OK, "Failed to add a buffer, hr %#x.\n", hr);
4781 IMFMediaBuffer_Release(media_buffer);
4783 status = 0;
4784 memset(&buffer, 0, sizeof(buffer));
4785 buffer.pSample = client_sample;
4786 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4787 ok(hr == S_OK, "Failed to get output, hr %#x.\n", hr);
4788 EXPECT_REF(sample, 1);
4790 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4791 ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "Failed to get output, hr %#x.\n", hr);
4793 /* Flushing. */
4794 hr = IMFTransform_ProcessInput(copier, 0, sample, 0);
4795 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4796 EXPECT_REF(sample, 2);
4798 hr = IMFTransform_ProcessMessage(copier, MFT_MESSAGE_COMMAND_FLUSH, 0);
4799 ok(hr == S_OK, "Failed to flush, hr %#x.\n", hr);
4800 EXPECT_REF(sample, 1);
4802 IMFSample_Release(sample);
4803 IMFSample_Release(client_sample);
4805 IMFMediaType_Release(mediatype);
4806 IMFTransform_Release(copier);
4809 static void sample_copier_process(IMFTransform *copier, IMFMediaBuffer *input_buffer,
4810 IMFMediaBuffer *output_buffer)
4812 IMFSample *input_sample, *output_sample;
4813 MFT_OUTPUT_DATA_BUFFER buffer;
4814 DWORD status;
4815 HRESULT hr;
4817 hr = MFCreateSample(&input_sample);
4818 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4820 hr = MFCreateSample(&output_sample);
4821 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
4823 hr = IMFSample_AddBuffer(input_sample, input_buffer);
4824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4826 hr = IMFSample_AddBuffer(output_sample, output_buffer);
4827 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4829 hr = IMFTransform_ProcessInput(copier, 0, input_sample, 0);
4830 ok(hr == S_OK, "Failed to process input, hr %#x.\n", hr);
4832 status = 0;
4833 memset(&buffer, 0, sizeof(buffer));
4834 buffer.pSample = output_sample;
4835 hr = IMFTransform_ProcessOutput(copier, 0, 1, &buffer, &status);
4836 ok(hr == S_OK, "Failed to get output, hr %#x.\n", hr);
4838 IMFSample_Release(input_sample);
4839 IMFSample_Release(output_sample);
4842 static void test_sample_copier_output_processing(void)
4844 IMFMediaBuffer *input_buffer, *output_buffer;
4845 MFT_OUTPUT_STREAM_INFO output_info;
4846 IMFMediaType *mediatype;
4847 IMFTransform *copier;
4848 DWORD max_length;
4849 HRESULT hr;
4850 BYTE *ptr;
4852 hr = MFCreateSampleCopierMFT(&copier);
4853 ok(hr == S_OK, "Failed to create sample copier, hr %#x.\n", hr);
4855 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
4856 hr = MFCreateMediaType(&mediatype);
4857 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4859 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4860 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4862 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
4863 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4865 hr = IMFMediaType_SetUINT64(mediatype, &MF_MT_FRAME_SIZE, ((UINT64)16) << 32 | 16);
4866 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4868 hr = IMFTransform_SetInputType(copier, 0, mediatype, 0);
4869 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4871 hr = IMFTransform_SetOutputType(copier, 0, mediatype, 0);
4872 ok(hr == S_OK, "Failed to set input type, hr %#x.\n", hr);
4874 /* Source and destination are linear buffers, destination is twice as large. */
4875 hr = IMFTransform_GetOutputStreamInfo(copier, 0, &output_info);
4876 ok(hr == S_OK, "Failed to get output info, hr %#x.\n", hr);
4878 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &output_buffer);
4879 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4881 hr = IMFMediaBuffer_Lock(output_buffer, &ptr, &max_length, NULL);
4882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4883 memset(ptr, 0xcc, max_length);
4884 hr = IMFMediaBuffer_Unlock(output_buffer);
4885 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4887 hr = MFCreateAlignedMemoryBuffer(output_info.cbSize, output_info.cbAlignment, &input_buffer);
4888 ok(hr == S_OK, "Failed to create media buffer, hr %#x.\n", hr);
4890 hr = IMFMediaBuffer_Lock(input_buffer, &ptr, &max_length, NULL);
4891 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4892 memset(ptr, 0xaa, max_length);
4893 hr = IMFMediaBuffer_Unlock(input_buffer);
4894 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4895 hr = IMFMediaBuffer_SetCurrentLength(input_buffer, 4);
4896 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4898 sample_copier_process(copier, input_buffer, output_buffer);
4900 hr = IMFMediaBuffer_Lock(output_buffer, &ptr, &max_length, NULL);
4901 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4902 ok(ptr[0] == 0xaa && ptr[4] == 0xcc, "Unexpected buffer contents.\n");
4904 hr = IMFMediaBuffer_Unlock(output_buffer);
4905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4907 IMFMediaType_Release(mediatype);
4908 IMFTransform_Release(copier);
4911 static void test_MFGetTopoNodeCurrentType(void)
4913 IMFMediaType *media_type, *media_type2;
4914 IMFTopologyNode *node;
4915 HRESULT hr;
4917 /* Tee node. */
4918 hr = MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE, &node);
4919 ok(hr == S_OK, "Failed to create a node, hr %#x.\n", hr);
4921 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
4922 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4924 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4925 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4927 hr = MFCreateMediaType(&media_type2);
4928 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4930 hr = IMFMediaType_SetGUID(media_type2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4931 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4933 /* Input type returned, if set. */
4934 hr = IMFTopologyNode_SetInputPrefType(node, 0, media_type2);
4935 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4937 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4938 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4939 ok(media_type == media_type2, "Unexpected pointer.\n");
4940 IMFMediaType_Release(media_type);
4942 hr = IMFTopologyNode_SetInputPrefType(node, 0, NULL);
4943 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4945 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4946 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4948 /* Set second output. */
4949 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
4950 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4952 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4953 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4955 hr = IMFTopologyNode_SetOutputPrefType(node, 1, NULL);
4956 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4958 /* Set first output. */
4959 hr = IMFTopologyNode_SetOutputPrefType(node, 0, media_type2);
4960 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4962 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4963 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4964 ok(media_type == media_type2, "Unexpected pointer.\n");
4965 IMFMediaType_Release(media_type);
4967 hr = IMFTopologyNode_SetOutputPrefType(node, 0, NULL);
4968 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4970 /* Set primary output. */
4971 hr = IMFTopologyNode_SetOutputPrefType(node, 1, media_type2);
4972 ok(hr == S_OK, "Failed to set media type, hr %#x.\n", hr);
4974 hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_PRIMARYOUTPUT, 1);
4975 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4977 hr = MFGetTopoNodeCurrentType(node, 0, FALSE, &media_type);
4978 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4979 ok(media_type == media_type2, "Unexpected pointer.\n");
4980 IMFMediaType_Release(media_type);
4982 hr = MFGetTopoNodeCurrentType(node, 0, TRUE, &media_type);
4983 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4984 ok(media_type == media_type2, "Unexpected pointer.\n");
4985 IMFMediaType_Release(media_type);
4987 IMFTopologyNode_Release(node);
4988 IMFMediaType_Release(media_type2);
4991 START_TEST(mf)
4993 test_topology();
4994 test_topology_tee_node();
4995 test_topology_loader();
4996 test_topology_loader_evr();
4997 test_MFGetService();
4998 test_sequencer_source();
4999 test_media_session();
5000 test_MFShutdownObject();
5001 test_presentation_clock();
5002 test_sample_grabber();
5003 test_sample_grabber_is_mediatype_supported();
5004 test_video_processor();
5005 test_quality_manager();
5006 test_sar();
5007 test_evr();
5008 test_MFCreateSimpleTypeHandler();
5009 test_MFGetSupportedMimeTypes();
5010 test_MFGetSupportedSchemes();
5011 test_sample_copier();
5012 test_sample_copier_output_processing();
5013 test_MFGetTopoNodeCurrentType();