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