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 static HRESULT (WINAPI
*pMFCreateSampleCopierMFT
)(IMFTransform
**copier
);
51 static HRESULT (WINAPI
*pMFGetTopoNodeCurrentType
)(IMFTopologyNode
*node
, DWORD stream
, BOOL output
, IMFMediaType
**type
);
53 static BOOL
is_vista(void)
55 return !pMFGetTopoNodeCurrentType
;
58 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
59 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
63 refcount
= IUnknown_Release(obj
);
64 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %d, expected %d.\n", refcount
,
68 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
69 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
71 IUnknown
*iface
= iface_ptr
;
72 HRESULT hr
, expected_hr
;
75 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
77 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
78 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
80 IUnknown_Release(unk
);
83 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
84 static void check_service_interface_(unsigned int line
, void *iface_ptr
, REFGUID service
, REFIID iid
, BOOL supported
)
86 IUnknown
*iface
= iface_ptr
;
87 HRESULT hr
, expected_hr
;
90 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
92 hr
= MFGetService(iface
, service
, iid
, (void **)&unk
);
93 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#x, expected %#x.\n", hr
, expected_hr
);
95 IUnknown_Release(unk
);
98 static HWND
create_window(void)
100 RECT r
= {0, 0, 640, 480};
102 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
104 return CreateWindowA("static", "mf_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
105 0, 0, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
108 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
110 if (IsEqualIID(riid
, &IID_IUnknown
))
113 IUnknown_AddRef(iface
);
118 return E_NOINTERFACE
;
121 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
126 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
131 static const IUnknownVtbl test_unk_vtbl
=
133 test_unk_QueryInterface
,
138 static void test_topology(void)
140 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
141 IMFCollection
*collection
, *collection2
;
142 IUnknown test_unk2
= { &test_unk_vtbl
};
143 IUnknown test_unk
= { &test_unk_vtbl
};
144 IMFTopologyNode
*node
, *node2
, *node3
;
145 IMFTopology
*topology
, *topology2
;
146 MF_TOPOLOGY_TYPE node_type
;
154 hr
= MFCreateTopology(NULL
);
155 ok(hr
== E_POINTER
, "got %#x\n", hr
);
157 hr
= MFCreateTopology(&topology
);
158 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
159 hr
= IMFTopology_GetTopologyID(topology
, &id
);
160 ok(hr
== S_OK
, "Failed to get id, hr %#x.\n", hr
);
161 ok(id
== 1, "Unexpected id.\n");
163 hr
= MFCreateTopology(&topology2
);
164 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
165 hr
= IMFTopology_GetTopologyID(topology2
, &id
);
166 ok(hr
== S_OK
, "Failed to get id, hr %#x.\n", hr
);
167 ok(id
== 2, "Unexpected id.\n");
169 IMFTopology_Release(topology
);
171 hr
= MFCreateTopology(&topology
);
172 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
173 hr
= IMFTopology_GetTopologyID(topology
, &id
);
174 ok(hr
== S_OK
, "Failed to get id, hr %#x.\n", hr
);
175 ok(id
== 3, "Unexpected id.\n");
177 IMFTopology_Release(topology2
);
179 /* No attributes by default. */
180 for (node_type
= MF_TOPOLOGY_OUTPUT_NODE
; node_type
< MF_TOPOLOGY_TEE_NODE
; ++node_type
)
182 hr
= MFCreateTopologyNode(node_type
, &node
);
183 ok(hr
== S_OK
, "Failed to create a node for type %d, hr %#x.\n", node_type
, hr
);
184 hr
= IMFTopologyNode_GetCount(node
, &count
);
185 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
186 ok(!count
, "Unexpected attribute count %u.\n", count
);
187 IMFTopologyNode_Release(node
);
190 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, NULL
);
191 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
193 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
194 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
196 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
197 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
199 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
200 ok(hr
== S_OK
, "Failed to get node id, hr %#x.\n", hr
);
201 ok(((id
>> 32) == GetCurrentProcessId()) && !!(id
& 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id
));
203 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
204 ok(hr
== S_OK
, "Failed to set node id, hr %#x.\n", hr
);
206 hr
= IMFTopology_GetNodeCount(topology
, NULL
);
207 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
209 hr
= IMFTopology_AddNode(topology
, NULL
);
210 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
213 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
214 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
215 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
217 /* Same id, different nodes. */
218 hr
= IMFTopology_AddNode(topology
, node
);
219 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
222 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
223 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
224 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
226 hr
= IMFTopology_AddNode(topology
, node2
);
227 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
228 IMFTopologyNode_Release(node2
);
230 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
231 ok(hr
== S_OK
, "Failed to get a node, hr %#x.\n", hr
);
232 ok(node2
== node
, "Unexpected node.\n");
233 IMFTopologyNode_Release(node2
);
235 /* Change node id, add it again. */
236 hr
= IMFTopologyNode_SetTopoNodeID(node
, ++id
);
237 ok(hr
== S_OK
, "Failed to set node id, hr %#x.\n", hr
);
239 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
240 ok(hr
== S_OK
, "Failed to get a node, hr %#x.\n", hr
);
241 ok(node2
== node
, "Unexpected node.\n");
242 IMFTopologyNode_Release(node2
);
244 hr
= IMFTopology_GetNodeByID(topology
, id
+ 1, &node2
);
245 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#x.\n", hr
);
247 hr
= IMFTopology_AddNode(topology
, node
);
248 ok(hr
== E_INVALIDARG
, "Failed to add a node, hr %#x.\n", hr
);
250 hr
= IMFTopology_GetNode(topology
, 0, &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 hr
= IMFTopology_GetNode(topology
, 1, NULL
);
256 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
258 hr
= IMFTopology_GetNode(topology
, 1, &node2
);
259 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#x.\n", hr
);
261 hr
= IMFTopology_GetNode(topology
, -2, &node2
);
262 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#x.\n", hr
);
264 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
265 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
266 hr
= IMFTopology_AddNode(topology
, node2
);
267 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
268 IMFTopologyNode_Release(node2
);
271 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
272 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
273 ok(node_count
== 2, "Unexpected node count %u.\n", node_count
);
275 /* Remove with detached node, existing id. */
276 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
277 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
278 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
279 ok(hr
== S_OK
, "Failed to set node id, hr %#x.\n", hr
);
280 hr
= IMFTopology_RemoveNode(topology
, node2
);
281 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
282 IMFTopologyNode_Release(node2
);
284 hr
= IMFTopology_RemoveNode(topology
, node
);
285 ok(hr
== S_OK
, "Failed to remove a node, hr %#x.\n", hr
);
288 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
289 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
290 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
292 hr
= IMFTopology_Clear(topology
);
293 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
296 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
297 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
298 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
300 hr
= IMFTopology_Clear(topology
);
301 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
303 hr
= IMFTopologyNode_SetTopoNodeID(node
, 123);
304 ok(hr
== S_OK
, "Failed to set node id, hr %#x.\n", hr
);
306 IMFTopologyNode_Release(node
);
308 /* Change id for attached node. */
309 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
310 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
312 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
313 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
315 hr
= IMFTopology_AddNode(topology
, node
);
316 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
318 hr
= IMFTopology_AddNode(topology
, node2
);
319 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
321 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
322 ok(hr
== S_OK
, "Failed to get node id, hr %#x.\n", hr
);
324 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
325 ok(hr
== S_OK
, "Failed to get node id, hr %#x.\n", hr
);
327 hr
= IMFTopology_GetNodeByID(topology
, id
, &node3
);
328 ok(hr
== S_OK
, "Failed to get a node, hr %#x.\n", hr
);
329 ok(node3
== node
, "Unexpected node.\n");
330 IMFTopologyNode_Release(node3
);
332 IMFTopologyNode_Release(node
);
333 IMFTopologyNode_Release(node2
);
335 /* Source/output collections. */
336 hr
= IMFTopology_Clear(topology
);
337 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
339 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
340 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
342 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
343 ok(hr
== S_OK
, "Failed to get source node collection, hr %#x.\n", hr
);
344 ok(!!collection
, "Unexpected object pointer.\n");
346 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection2
);
347 ok(hr
== S_OK
, "Failed to get source node collection, hr %#x.\n", hr
);
348 ok(!!collection2
, "Unexpected object pointer.\n");
349 ok(collection2
!= collection
, "Expected cloned collection.\n");
351 hr
= IMFCollection_GetElementCount(collection
, &size
);
352 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
353 ok(!size
, "Unexpected item count.\n");
355 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)collection
);
356 ok(hr
== S_OK
, "Failed to add element, hr %#x.\n", hr
);
358 hr
= IMFCollection_GetElementCount(collection
, &size
);
359 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
360 ok(size
== 1, "Unexpected item count.\n");
362 hr
= IMFCollection_GetElementCount(collection2
, &size
);
363 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
364 ok(!size
, "Unexpected item count.\n");
366 IMFCollection_Release(collection2
);
367 IMFCollection_Release(collection
);
369 /* Add some nodes. */
370 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
371 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
373 hr
= IMFTopology_GetOutputNodeCollection(topology
, NULL
);
374 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
376 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
377 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
378 hr
= IMFTopology_AddNode(topology
, node
);
379 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
380 IMFTopologyNode_Release(node
);
382 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
383 ok(hr
== S_OK
, "Failed to get source node collection, hr %#x.\n", hr
);
384 ok(!!collection
, "Unexpected object pointer.\n");
385 hr
= IMFCollection_GetElementCount(collection
, &size
);
386 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
387 ok(size
== 1, "Unexpected item count.\n");
388 IMFCollection_Release(collection
);
390 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
391 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
392 hr
= IMFTopology_AddNode(topology
, node
);
393 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
394 IMFTopologyNode_Release(node
);
396 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
397 ok(hr
== S_OK
, "Failed to get source node collection, hr %#x.\n", hr
);
398 ok(!!collection
, "Unexpected object pointer.\n");
399 hr
= IMFCollection_GetElementCount(collection
, &size
);
400 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
401 ok(size
== 1, "Unexpected item count.\n");
402 IMFCollection_Release(collection
);
404 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
405 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
406 hr
= IMFTopology_AddNode(topology
, node
);
407 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
408 IMFTopologyNode_Release(node
);
410 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
411 ok(hr
== S_OK
, "Failed to get source node collection, hr %#x.\n", hr
);
412 ok(!!collection
, "Unexpected object pointer.\n");
413 hr
= IMFCollection_GetElementCount(collection
, &size
);
414 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
415 ok(size
== 1, "Unexpected item count.\n");
416 IMFCollection_Release(collection
);
418 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
419 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
420 hr
= IMFTopology_AddNode(topology
, node
);
421 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
423 /* Associated object. */
424 hr
= IMFTopologyNode_SetObject(node
, NULL
);
425 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
427 hr
= IMFTopologyNode_GetObject(node
, NULL
);
428 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
430 object
= (void *)0xdeadbeef;
431 hr
= IMFTopologyNode_GetObject(node
, &object
);
432 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
433 ok(!object
, "Unexpected object %p.\n", object
);
435 hr
= IMFTopologyNode_SetObject(node
, &test_unk
);
436 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
438 hr
= IMFTopologyNode_GetObject(node
, &object
);
439 ok(hr
== S_OK
, "Failed to get object, hr %#x.\n", hr
);
440 ok(object
== &test_unk
, "Unexpected object %p.\n", object
);
441 IUnknown_Release(object
);
443 hr
= IMFTopologyNode_SetObject(node
, &test_unk2
);
444 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
446 hr
= IMFTopologyNode_GetCount(node
, &count
);
447 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
448 ok(count
== 0, "Unexpected attribute count %u.\n", count
);
450 hr
= IMFTopologyNode_SetGUID(node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &MF_TOPONODE_TRANSFORM_OBJECTID
);
451 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
453 hr
= IMFTopologyNode_SetObject(node
, NULL
);
454 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
456 object
= (void *)0xdeadbeef;
457 hr
= IMFTopologyNode_GetObject(node
, &object
);
458 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
459 ok(!object
, "Unexpected object %p.\n", object
);
461 hr
= IMFTopologyNode_GetCount(node
, &count
);
462 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
463 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
465 /* Preferred stream types. */
466 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
467 ok(hr
== S_OK
, "Failed to get input count, hr %#x.\n", hr
);
468 ok(count
== 0, "Unexpected count %u.\n", count
);
470 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype
);
471 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
473 hr
= MFCreateMediaType(&mediatype
);
474 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
476 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
477 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
479 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
480 ok(hr
== S_OK
, "Failed to get preferred type, hr %#x.\n", hr
);
481 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
482 IMFMediaType_Release(mediatype2
);
484 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
485 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
487 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
488 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
489 ok(!mediatype2
, "Unexpected mediatype instance.\n");
491 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
492 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
494 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
495 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
497 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
498 ok(hr
== S_OK
, "Failed to get input count, hr %#x.\n", hr
);
499 ok(count
== 2, "Unexpected count %u.\n", count
);
501 hr
= IMFTopologyNode_GetOutputCount(node
, &count
);
502 ok(hr
== S_OK
, "Failed to get input count, hr %#x.\n", hr
);
503 ok(count
== 0, "Unexpected count %u.\n", count
);
505 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, mediatype
);
506 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
508 IMFTopologyNode_Release(node
);
511 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
512 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
514 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
515 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
517 hr
= IMFTopologyNode_SetOutputPrefType(node
, 2, mediatype
);
518 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
520 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
521 ok(hr
== E_FAIL
, "Failed to get preferred type, hr %#x.\n", hr
);
522 ok(!mediatype2
, "Unexpected mediatype instance.\n");
524 hr
= IMFTopologyNode_GetOutputCount(node
, &count
);
525 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
526 ok(count
== 3, "Unexpected count %u.\n", count
);
528 IMFTopologyNode_Release(node
);
531 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_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
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
537 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
538 ok(hr
== S_OK
, "Failed to get preferred type, hr %#x.\n", hr
);
539 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
540 IMFMediaType_Release(mediatype2
);
542 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
543 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
545 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
546 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
547 ok(count
== 0, "Unexpected count %u.\n", count
);
549 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
550 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#x.\n", hr
);
552 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
553 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#x.\n", hr
);
555 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
556 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
558 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
559 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
561 hr
= MFCreateMediaType(&mediatype2
);
562 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
564 /* Changing output type does not change input type. */
565 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype2
);
566 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
568 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype3
);
569 ok(hr
== S_OK
, "Failed to get preferred type, hr %#x.\n", hr
);
570 ok(mediatype3
== mediatype
, "Unexpected mediatype instance.\n");
571 IMFMediaType_Release(mediatype3
);
573 IMFMediaType_Release(mediatype2
);
575 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
576 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
577 ok(count
== 0, "Unexpected count %u.\n", count
);
579 hr
= IMFTopologyNode_GetOutputCount(node
, &count
);
580 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
581 ok(count
== 5, "Unexpected count %u.\n", count
);
583 IMFTopologyNode_Release(node
);
585 /* Transform node. */
586 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
587 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
589 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
590 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
592 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
593 ok(hr
== S_OK
, "Failed to get input count, hr %#x.\n", hr
);
594 ok(count
== 4, "Unexpected count %u.\n", count
);
596 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
597 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
599 hr
= IMFTopologyNode_GetInputCount(node
, &count
);
600 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
601 ok(count
== 4, "Unexpected count %u.\n", count
);
603 hr
= IMFTopologyNode_GetOutputCount(node
, &count
);
604 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
605 ok(count
== 5, "Unexpected count %u.\n", count
);
607 IMFTopologyNode_Release(node
);
609 IMFMediaType_Release(mediatype
);
611 hr
= IMFTopology_GetOutputNodeCollection(topology
, &collection
);
612 ok(hr
== S_OK
|| broken(hr
== E_FAIL
) /* before Win8 */, "Failed to get output node collection, hr %#x.\n", hr
);
615 ok(!!collection
, "Unexpected object pointer.\n");
616 hr
= IMFCollection_GetElementCount(collection
, &size
);
617 ok(hr
== S_OK
, "Failed to get item count, hr %#x.\n", hr
);
618 ok(size
== 1, "Unexpected item count.\n");
619 IMFCollection_Release(collection
);
622 IMFTopology_Release(topology
);
625 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
626 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
628 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
629 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
632 EXPECT_REF(node2
, 1);
634 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
635 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
638 EXPECT_REF(node2
, 2);
640 IMFTopologyNode_Release(node
);
643 EXPECT_REF(node2
, 2);
645 IMFTopologyNode_Release(node2
);
648 EXPECT_REF(node2
, 1);
650 hr
= IMFTopologyNode_GetNodeType(node2
, &node_type
);
651 ok(hr
== S_OK
, "Failed to get node type, hr %#x.\n", hr
);
653 IMFTopologyNode_Release(node
);
655 /* Connect within topology. */
656 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
657 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
659 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
660 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
662 hr
= MFCreateTopology(&topology
);
663 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
665 hr
= IMFTopology_AddNode(topology
, node
);
666 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
668 hr
= IMFTopology_AddNode(topology
, node2
);
669 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
672 EXPECT_REF(node2
, 2);
674 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
675 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
678 EXPECT_REF(node2
, 3);
680 hr
= IMFTopology_Clear(topology
);
681 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
684 EXPECT_REF(node2
, 1);
686 /* Removing connected node breaks connection. */
687 hr
= IMFTopology_AddNode(topology
, node
);
688 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
690 hr
= IMFTopology_AddNode(topology
, node2
);
691 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
693 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
694 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
696 hr
= IMFTopology_RemoveNode(topology
, node
);
697 ok(hr
== S_OK
, "Failed to remove a node, hr %#x.\n", hr
);
700 EXPECT_REF(node2
, 2);
702 hr
= IMFTopologyNode_GetOutput(node
, 0, &node3
, &index
);
703 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#x.\n", hr
);
705 hr
= IMFTopology_AddNode(topology
, node
);
706 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
708 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
709 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
711 hr
= IMFTopology_RemoveNode(topology
, node2
);
712 ok(hr
== S_OK
, "Failed to remove a node, hr %#x.\n", hr
);
715 EXPECT_REF(node2
, 1);
717 IMFTopologyNode_Release(node
);
718 IMFTopologyNode_Release(node2
);
720 /* Cloning nodes of different types. */
721 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
722 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
724 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
725 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
727 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
728 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#x.\n", hr
);
730 IMFTopologyNode_Release(node2
);
732 /* Cloning preferred types. */
733 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
734 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
736 hr
= MFCreateMediaType(&mediatype
);
737 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
739 hr
= IMFTopologyNode_SetOutputPrefType(node2
, 0, mediatype
);
740 ok(hr
== S_OK
, "Failed to set preferred type, hr %#x.\n", hr
);
742 /* Vista checks for additional attributes. */
743 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
744 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#x.\n", hr
);
746 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
747 ok(hr
== S_OK
, "Failed to get preferred type, hr %#x.\n", hr
);
748 ok(mediatype
== mediatype2
, "Unexpected media type.\n");
750 IMFMediaType_Release(mediatype2
);
751 IMFMediaType_Release(mediatype
);
753 IMFTopologyNode_Release(node2
);
755 /* Existing preferred types are not cleared. */
756 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
757 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
759 hr
= IMFTopologyNode_GetOutputCount(node
, &count
);
760 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
761 ok(count
== 1, "Unexpected output count.\n");
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_GetOutputCount(node
, &count
);
767 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
768 ok(count
== 1, "Unexpected output count.\n");
770 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
771 ok(hr
== S_OK
, "Failed to get preferred type, hr %#x.\n", hr
);
772 ok(!!mediatype2
, "Unexpected media type.\n");
773 IMFMediaType_Release(mediatype2
);
775 hr
= IMFTopologyNode_CloneFrom(node2
, node
);
776 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#x.\n", hr
);
778 hr
= IMFTopologyNode_GetOutputCount(node2
, &count
);
779 ok(hr
== S_OK
, "Failed to get output count, hr %#x.\n", hr
);
780 ok(count
== 1, "Unexpected output count.\n");
782 IMFTopologyNode_Release(node2
);
783 IMFTopologyNode_Release(node
);
785 /* Add one node, connect to another that hasn't been added. */
786 hr
= IMFTopology_Clear(topology
);
787 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
789 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
790 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
792 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
793 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
795 hr
= IMFTopology_AddNode(topology
, node
);
796 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
798 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
799 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
800 ok(node_count
== 1, "Unexpected node count.\n");
802 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 0);
803 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
805 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
806 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
807 ok(node_count
== 1, "Unexpected node count.\n");
809 IMFTopologyNode_Release(node
);
810 IMFTopologyNode_Release(node2
);
812 /* Add same node to different topologies. */
813 hr
= IMFTopology_Clear(topology
);
814 ok(hr
== S_OK
, "Failed to clear topology, hr %#x.\n", hr
);
816 hr
= MFCreateTopology(&topology2
);
817 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
819 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
820 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
822 hr
= IMFTopology_AddNode(topology
, node
);
823 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
826 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
827 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
828 ok(node_count
== 1, "Unexpected node count.\n");
830 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
831 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
832 ok(node_count
== 0, "Unexpected node count.\n");
834 hr
= IMFTopology_AddNode(topology2
, node
);
835 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
838 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
839 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
840 ok(node_count
== 1, "Unexpected node count.\n");
842 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
843 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
844 ok(node_count
== 1, "Unexpected node count.\n");
846 IMFTopology_Release(topology2
);
847 IMFTopology_Release(topology
);
850 static void test_topology_tee_node(void)
852 IMFTopologyNode
*src_node
, *tee_node
;
853 IMFMediaType
*mediatype
, *mediatype2
;
854 IMFTopology
*topology
;
858 hr
= MFCreateTopology(&topology
);
859 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
861 hr
= MFCreateMediaType(&mediatype
);
862 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
864 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &tee_node
);
865 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
867 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
868 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
870 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 0, mediatype
);
871 ok(hr
== S_OK
, "Failed to set type, hr %#x.\n", hr
);
873 /* Even though tee node has only one input and source has only one output,
874 it's possible to connect to higher inputs/outputs. */
876 /* SRC(0) -> TEE(0) */
877 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 0);
878 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
880 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
881 ok(hr
== S_OK
, "Failed to get count, hr %#x.\n", hr
);
882 ok(count
== 1, "Unexpected count %u.\n", count
);
884 hr
= IMFTopologyNode_GetInputPrefType(tee_node
, 0, &mediatype2
);
885 ok(hr
== S_OK
, "Failed to get type, hr %#x.\n", hr
);
886 ok(mediatype2
== mediatype
, "Unexpected type.\n");
887 IMFMediaType_Release(mediatype2
);
889 /* SRC(0) -> TEE(1) */
890 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 1);
891 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
893 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
894 ok(hr
== S_OK
, "Failed to get count, hr %#x.\n", hr
);
895 ok(count
== 2, "Unexpected count %u.\n", count
);
897 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 1, mediatype
);
898 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#x.\n", hr
);
900 /* SRC(1) -> TEE(1) */
901 hr
= IMFTopologyNode_ConnectOutput(src_node
, 1, tee_node
, 1);
902 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
904 hr
= IMFTopologyNode_GetOutputCount(src_node
, &count
);
905 ok(hr
== S_OK
, "Failed to get count, hr %#x.\n", hr
);
906 ok(count
== 2, "Unexpected count %u.\n", count
);
908 IMFMediaType_Release(mediatype
);
909 IMFTopologyNode_Release(src_node
);
910 IMFTopologyNode_Release(tee_node
);
911 IMFTopology_Release(topology
);
914 static HRESULT WINAPI
test_getservice_QI(IMFGetService
*iface
, REFIID riid
, void **obj
)
916 if (IsEqualIID(riid
, &IID_IMFGetService
) || IsEqualIID(riid
, &IID_IUnknown
))
923 return E_NOINTERFACE
;
926 static ULONG WINAPI
test_getservice_AddRef(IMFGetService
*iface
)
931 static ULONG WINAPI
test_getservice_Release(IMFGetService
*iface
)
936 static HRESULT WINAPI
test_getservice_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
938 *obj
= (void *)0xdeadbeef;
942 static const IMFGetServiceVtbl testmfgetservicevtbl
=
945 test_getservice_AddRef
,
946 test_getservice_Release
,
947 test_getservice_GetService
,
950 static IMFGetService test_getservice
= { &testmfgetservicevtbl
};
952 static HRESULT WINAPI
testservice_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
954 if (IsEqualIID(riid
, &IID_IUnknown
))
962 if (IsEqualIID(riid
, &IID_IMFGetService
))
965 return E_NOINTERFACE
;
968 static HRESULT WINAPI
testservice2_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
970 if (IsEqualIID(riid
, &IID_IUnknown
))
976 if (IsEqualIID(riid
, &IID_IMFGetService
))
978 *obj
= &test_getservice
;
983 return E_NOINTERFACE
;
986 static ULONG WINAPI
testservice_AddRef(IUnknown
*iface
)
991 static ULONG WINAPI
testservice_Release(IUnknown
*iface
)
996 static const IUnknownVtbl testservicevtbl
=
1000 testservice_Release
,
1003 static const IUnknownVtbl testservice2vtbl
=
1007 testservice_Release
,
1010 static IUnknown testservice
= { &testservicevtbl
};
1011 static IUnknown testservice2
= { &testservice2vtbl
};
1013 static void test_MFGetService(void)
1018 hr
= MFGetService(NULL
, NULL
, NULL
, NULL
);
1019 ok(hr
== E_POINTER
, "Unexpected return value %#x.\n", hr
);
1021 unk
= (void *)0xdeadbeef;
1022 hr
= MFGetService(NULL
, NULL
, NULL
, (void **)&unk
);
1023 ok(hr
== E_POINTER
, "Unexpected return value %#x.\n", hr
);
1024 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1026 hr
= MFGetService(&testservice
, NULL
, NULL
, NULL
);
1027 ok(hr
== 0x82eddead, "Unexpected return value %#x.\n", hr
);
1029 unk
= (void *)0xdeadbeef;
1030 hr
= MFGetService(&testservice
, NULL
, NULL
, (void **)&unk
);
1031 ok(hr
== 0x82eddead, "Unexpected return value %#x.\n", hr
);
1032 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1035 hr
= MFGetService(&testservice2
, NULL
, NULL
, (void **)&unk
);
1036 ok(hr
== 0x83eddead, "Unexpected return value %#x.\n", hr
);
1037 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1040 static void test_sequencer_source(void)
1042 IMFSequencerSource
*seq_source
;
1045 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1046 ok(hr
== S_OK
, "Startup failure, hr %#x.\n", hr
);
1048 hr
= MFCreateSequencerSource(NULL
, &seq_source
);
1049 ok(hr
== S_OK
, "Failed to create sequencer source, hr %#x.\n", hr
);
1051 check_interface(seq_source
, &IID_IMFMediaSourceTopologyProvider
, TRUE
);
1053 IMFSequencerSource_Release(seq_source
);
1056 ok(hr
== S_OK
, "Shutdown failure, hr %#x.\n", hr
);
1059 struct test_callback
1061 IMFAsyncCallback IMFAsyncCallback_iface
;
1064 static HRESULT WINAPI
testcallback_QueryInterface(IMFAsyncCallback
*iface
, REFIID riid
, void **obj
)
1066 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
1067 IsEqualIID(riid
, &IID_IUnknown
))
1070 IMFAsyncCallback_AddRef(iface
);
1075 return E_NOINTERFACE
;
1078 static ULONG WINAPI
testcallback_AddRef(IMFAsyncCallback
*iface
)
1083 static ULONG WINAPI
testcallback_Release(IMFAsyncCallback
*iface
)
1088 static HRESULT WINAPI
testcallback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
1090 ok(flags
!= NULL
&& queue
!= NULL
, "Unexpected arguments.\n");
1094 static HRESULT WINAPI
testcallback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1096 ok(result
!= NULL
, "Unexpected result object.\n");
1101 static const IMFAsyncCallbackVtbl testcallbackvtbl
=
1103 testcallback_QueryInterface
,
1104 testcallback_AddRef
,
1105 testcallback_Release
,
1106 testcallback_GetParameters
,
1107 testcallback_Invoke
,
1110 static void init_test_callback(struct test_callback
*callback
)
1112 callback
->IMFAsyncCallback_iface
.lpVtbl
= &testcallbackvtbl
;
1115 static void test_session_events(IMFMediaSession
*session
)
1117 struct test_callback callback
, callback2
;
1118 IMFAsyncResult
*result
;
1119 IMFMediaEvent
*event
;
1122 init_test_callback(&callback
);
1123 init_test_callback(&callback2
);
1125 hr
= IMFMediaSession_GetEvent(session
, MF_EVENT_FLAG_NO_WAIT
, &event
);
1126 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#x.\n", hr
);
1129 hr
= IMFMediaSession_BeginGetEvent(session
, NULL
, NULL
);
1130 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
1132 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1133 ok(hr
== S_OK
, "Failed to Begin*, hr %#x.\n", hr
);
1135 /* Same callback, same state. */
1136 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1137 ok(hr
== MF_S_MULTIPLE_BEGIN
, "Unexpected hr %#x.\n", hr
);
1139 /* Same callback, different state. */
1140 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
);
1141 ok(hr
== MF_E_MULTIPLE_BEGIN
, "Unexpected hr %#x.\n", hr
);
1143 /* Different callback, same state. */
1144 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1145 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#x.\n", hr
);
1147 /* Different callback, different state. */
1148 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1149 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#x.\n", hr
);
1151 hr
= MFCreateAsyncResult(NULL
, &callback
.IMFAsyncCallback_iface
, NULL
, &result
);
1152 ok(hr
== S_OK
, "Failed to create result, hr %#x.\n", hr
);
1154 hr
= IMFMediaSession_EndGetEvent(session
, result
, &event
);
1155 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
1157 /* Shutdown behavior. */
1158 hr
= IMFMediaSession_Shutdown(session
);
1159 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
1162 static void test_media_session(void)
1164 IMFRateControl
*rate_control
, *rate_control2
;
1165 MFCLOCK_PROPERTIES clock_props
;
1166 IMFRateSupport
*rate_support
;
1167 IMFAttributes
*attributes
;
1168 IMFMediaSession
*session
;
1169 IMFTopology
*topology
;
1170 IMFShutdown
*shutdown
;
1171 PROPVARIANT propvar
;
1179 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1180 ok(hr
== S_OK
, "Startup failure, hr %#x.\n", hr
);
1182 hr
= MFCreateMediaSession(NULL
, &session
);
1183 ok(hr
== S_OK
, "Failed to create media session, hr %#x.\n", hr
);
1185 check_interface(session
, &IID_IMFGetService
, TRUE
);
1186 check_interface(session
, &IID_IMFAttributes
, FALSE
);
1187 check_interface(session
, &IID_IMFTopologyNodeAttributeEditor
, FALSE
);
1189 hr
= MFGetService((IUnknown
*)session
, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE
, &IID_IMFTopologyNodeAttributeEditor
,
1191 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1193 check_interface(unk
, &IID_IMFMediaSession
, FALSE
);
1195 IUnknown_Release(unk
);
1197 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1198 ok(hr
== S_OK
, "Failed to get rate support interface, hr %#x.\n", hr
);
1200 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, (void **)&rate_control
);
1201 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#x.\n", hr
);
1203 hr
= MFGetService((IUnknown
*)session
, &MF_LOCAL_MFT_REGISTRATION_SERVICE
, &IID_IMFLocalMFTRegistration
, (void **)&unk
);
1204 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
) /* Vista */, "Failed to get registration service, hr %#x.\n", hr
);
1206 IUnknown_Release(unk
);
1208 hr
= IMFRateSupport_QueryInterface(rate_support
, &IID_IMFMediaSession
, (void **)&unk
);
1209 ok(hr
== S_OK
, "Failed to get session interface, hr %#x.\n", hr
);
1210 ok(unk
== (IUnknown
*)session
, "Unexpected pointer.\n");
1211 IUnknown_Release(unk
);
1213 hr
= IMFRateControl_GetRate(rate_control
, NULL
, NULL
);
1214 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
1217 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
1218 ok(hr
== S_OK
, "Failed to get playback rate, hr %#x.\n", hr
);
1219 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1221 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
1222 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
1226 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
1227 ok(hr
== S_OK
, "Failed to get playback rate, hr %#x.\n", hr
);
1228 ok(!thin
, "Unexpected thinning.\n");
1229 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1231 hr
= IMFMediaSession_GetClock(session
, &clock
);
1232 ok(hr
== S_OK
, "Failed to get clock, hr %#x.\n", hr
);
1234 check_interface(clock
, &IID_IMFPresentationClock
, TRUE
);
1236 hr
= IMFClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&rate_control2
);
1237 ok(hr
== S_OK
, "Failed to get rate control, hr %#x.\n", hr
);
1240 hr
= IMFRateControl_GetRate(rate_control2
, NULL
, &rate
);
1241 ok(hr
== S_OK
, "Failed to get clock rate, hr %#x.\n", hr
);
1242 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1244 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1246 ok(hr
== S_OK
, "Failed to set rate, hr %#x.\n", hr
);
1248 IMFRateControl_Release(rate_control2
);
1250 hr
= IMFClock_GetProperties(clock
, &clock_props
);
1251 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
1252 IMFClock_Release(clock
);
1254 IMFRateControl_Release(rate_control
);
1255 IMFRateSupport_Release(rate_support
);
1257 IMFMediaSession_Release(session
);
1259 hr
= MFCreateMediaSession(NULL
, &session
);
1260 ok(hr
== S_OK
, "Failed to create media session, hr %#x.\n", hr
);
1262 hr
= IMFMediaSession_GetClock(session
, &clock
);
1263 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1265 hr
= IMFClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
1266 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1268 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1269 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#x.\n", hr
);
1271 hr
= IMFMediaSession_Shutdown(session
);
1272 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
1274 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1275 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1276 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected shutdown status %u.\n", status
);
1278 IMFShutdown_Release(shutdown
);
1280 hr
= IMFMediaSession_ClearTopologies(session
);
1281 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1283 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, NULL
);
1284 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
1286 propvar
.vt
= VT_EMPTY
;
1287 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, &propvar
);
1288 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1290 hr
= IMFMediaSession_Pause(session
);
1291 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1293 hr
= IMFMediaSession_Stop(session
);
1294 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1296 hr
= IMFMediaSession_Close(session
);
1297 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1299 hr
= IMFMediaSession_GetClock(session
, &clock
);
1300 ok(hr
== MF_E_SHUTDOWN
|| broken(hr
== E_UNEXPECTED
) /* Win7 */, "Unexpected hr %#x.\n", hr
);
1302 hr
= IMFMediaSession_GetSessionCapabilities(session
, &caps
);
1303 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1305 hr
= IMFMediaSession_GetSessionCapabilities(session
, NULL
);
1306 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
1308 hr
= IMFMediaSession_GetFullTopology(session
, MFSESSION_GETFULLTOPOLOGY_CURRENT
, 0, &topology
);
1309 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1311 hr
= IMFMediaSession_Shutdown(session
);
1312 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
1314 IMFMediaSession_Release(session
);
1316 /* Custom topology loader, GUID is not registered. */
1317 hr
= MFCreateAttributes(&attributes
, 1);
1318 ok(hr
== S_OK
, "Failed to create attributes, hr %#x.\n", hr
);
1320 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_TOPOLOADER
, &MF_SESSION_TOPOLOADER
);
1321 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1323 hr
= MFCreateMediaSession(attributes
, &session
);
1324 ok(hr
== S_OK
, "Failed to create media session, hr %#x.\n", hr
);
1325 IMFMediaSession_Release(session
);
1327 /* Disabled quality manager. */
1328 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_QUALITY_MANAGER
, &GUID_NULL
);
1329 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1331 hr
= MFCreateMediaSession(attributes
, &session
);
1332 ok(hr
== S_OK
, "Failed to create media session, hr %#x.\n", hr
);
1333 IMFMediaSession_Release(session
);
1335 IMFAttributes_Release(attributes
);
1337 /* Basic events behavior. */
1338 hr
= MFCreateMediaSession(NULL
, &session
);
1339 ok(hr
== S_OK
, "Failed to create media session, hr %#x.\n", hr
);
1341 test_session_events(session
);
1343 IMFMediaSession_Release(session
);
1346 ok(hr
== S_OK
, "Shutdown failure, hr %#x.\n", hr
);
1349 static HRESULT WINAPI
test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
,
1352 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
1353 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
1354 IsEqualIID(riid
, &IID_IUnknown
))
1357 IMFSampleGrabberSinkCallback_AddRef(iface
);
1362 return E_NOINTERFACE
;
1365 static ULONG WINAPI
test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
1370 static ULONG WINAPI
test_grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
1375 static HRESULT WINAPI
test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
,
1381 static HRESULT WINAPI
test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1386 static HRESULT WINAPI
test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1391 static HRESULT WINAPI
test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1396 static HRESULT WINAPI
test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
, float rate
)
1401 static HRESULT WINAPI
test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
1402 IMFPresentationClock
*clock
)
1407 static HRESULT WINAPI
test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
1408 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
1413 static HRESULT WINAPI
test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
1418 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl
=
1420 test_grabber_callback_QueryInterface
,
1421 test_grabber_callback_AddRef
,
1422 test_grabber_callback_Release
,
1423 test_grabber_callback_OnClockStart
,
1424 test_grabber_callback_OnClockStop
,
1425 test_grabber_callback_OnClockPause
,
1426 test_grabber_callback_OnClockRestart
,
1427 test_grabber_callback_OnClockSetRate
,
1428 test_grabber_callback_OnSetPresentationClock
,
1429 test_grabber_callback_OnProcessSample
,
1430 test_grabber_callback_OnShutdown
,
1435 IMFMediaSource IMFMediaSource_iface
;
1439 static struct test_source
*impl_from_IMFMediaSource(IMFMediaSource
*iface
)
1441 return CONTAINING_RECORD(iface
, struct test_source
, IMFMediaSource_iface
);
1444 static HRESULT WINAPI
test_source_QueryInterface(IMFMediaSource
*iface
, REFIID riid
, void **out
)
1446 if (IsEqualIID(riid
, &IID_IMFMediaSource
)
1447 || IsEqualIID(riid
, &IID_IMFMediaEventGenerator
)
1448 || IsEqualIID(riid
, &IID_IUnknown
))
1455 return E_NOINTERFACE
;
1458 IMFMediaSource_AddRef(iface
);
1462 static ULONG WINAPI
test_source_AddRef(IMFMediaSource
*iface
)
1464 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1465 return InterlockedIncrement(&source
->refcount
);
1468 static ULONG WINAPI
test_source_Release(IMFMediaSource
*iface
)
1470 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1471 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
1474 HeapFree(GetProcessHeap(), 0, source
);
1479 static HRESULT WINAPI
test_source_GetEvent(IMFMediaSource
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1481 ok(0, "Unexpected call.\n");
1485 static HRESULT WINAPI
test_source_BeginGetEvent(IMFMediaSource
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
1487 ok(0, "Unexpected call.\n");
1491 static HRESULT WINAPI
test_source_EndGetEvent(IMFMediaSource
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
1493 ok(0, "Unexpected call.\n");
1497 static HRESULT WINAPI
test_source_QueueEvent(IMFMediaSource
*iface
, MediaEventType event_type
, REFGUID ext_type
,
1498 HRESULT hr
, const PROPVARIANT
*value
)
1500 ok(0, "Unexpected call.\n");
1504 static HRESULT WINAPI
test_source_GetCharacteristics(IMFMediaSource
*iface
, DWORD
*flags
)
1506 ok(0, "Unexpected call.\n");
1510 static HRESULT WINAPI
test_source_CreatePresentationDescriptor(IMFMediaSource
*iface
, IMFPresentationDescriptor
**pd
)
1512 ok(0, "Unexpected call.\n");
1516 static HRESULT WINAPI
test_source_Start(IMFMediaSource
*iface
, IMFPresentationDescriptor
*pd
, const GUID
*time_format
,
1517 const PROPVARIANT
*start_position
)
1519 ok(0, "Unexpected call.\n");
1523 static HRESULT WINAPI
test_source_Stop(IMFMediaSource
*iface
)
1525 ok(0, "Unexpected call.\n");
1529 static HRESULT WINAPI
test_source_Pause(IMFMediaSource
*iface
)
1531 ok(0, "Unexpected call.\n");
1535 static HRESULT WINAPI
test_source_Shutdown(IMFMediaSource
*iface
)
1537 ok(0, "Unexpected call.\n");
1541 static const IMFMediaSourceVtbl test_source_vtbl
=
1543 test_source_QueryInterface
,
1545 test_source_Release
,
1546 test_source_GetEvent
,
1547 test_source_BeginGetEvent
,
1548 test_source_EndGetEvent
,
1549 test_source_QueueEvent
,
1550 test_source_GetCharacteristics
,
1551 test_source_CreatePresentationDescriptor
,
1555 test_source_Shutdown
,
1558 static IMFMediaSource
*create_test_source(void)
1560 struct test_source
*source
;
1562 source
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*source
));
1563 source
->IMFMediaSource_iface
.lpVtbl
= &test_source_vtbl
;
1564 source
->refcount
= 1;
1566 return &source
->IMFMediaSource_iface
;
1575 static void init_media_type(IMFMediaType
*mediatype
, const GUID
*major
, const struct type_attr
*attrs
)
1579 hr
= IMFMediaType_DeleteAllItems(mediatype
);
1580 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1582 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, major
);
1583 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1587 if (IsEqualGUID(attrs
->key
, &MF_MT_SUBTYPE
))
1591 memcpy(&subtype
, IsEqualGUID(major
, &MFMediaType_Audio
) ? &MFAudioFormat_Base
: &MFVideoFormat_Base
,
1593 subtype
.Data1
= attrs
->value
;
1594 hr
= IMFMediaType_SetGUID(mediatype
, attrs
->key
, &subtype
);
1597 hr
= IMFMediaType_SetUINT32(mediatype
, attrs
->key
, attrs
->value
);
1598 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1604 static void init_source_node(IMFMediaType
*mediatype
, IMFMediaSource
*source
, IMFTopologyNode
*node
)
1606 IMFPresentationDescriptor
*pd
;
1607 IMFMediaTypeHandler
*handler
;
1608 IMFStreamDescriptor
*sd
;
1611 hr
= IMFTopologyNode_DeleteAllItems(node
);
1612 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1614 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
1615 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#x.\n", hr
);
1617 hr
= IMFStreamDescriptor_GetMediaTypeHandler(sd
, &handler
);
1618 ok(hr
== S_OK
, "Failed to get media type handler, hr %#x.\n", hr
);
1620 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
1621 ok(hr
== S_OK
, "Failed to set current media type, hr %#x.\n", hr
);
1623 IMFMediaTypeHandler_Release(handler
);
1625 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
1626 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#x.\n", hr
);
1628 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
1629 ok(hr
== S_OK
, "Failed to set node pd, hr %#x.\n", hr
);
1631 IMFPresentationDescriptor_Release(pd
);
1633 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
1634 ok(hr
== S_OK
, "Failed to set node sd, hr %#x.\n", hr
);
1638 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
1639 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1642 IMFStreamDescriptor_Release(sd
);
1645 static void init_sink_node(IMFActivate
*sink_activate
, unsigned int method
, IMFTopologyNode
*node
)
1647 IMFStreamSink
*stream_sink
;
1651 hr
= IMFTopologyNode_DeleteAllItems(node
);
1652 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1654 hr
= IMFActivate_ActivateObject(sink_activate
, &IID_IMFMediaSink
, (void **)&sink
);
1655 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
1657 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
1658 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
1660 IMFMediaSink_Release(sink
);
1662 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)stream_sink
);
1663 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
1665 IMFStreamSink_Release(stream_sink
);
1667 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_CONNECT_METHOD
, method
);
1668 ok(hr
== S_OK
, "Failed to set connect method, hr %#x.\n", hr
);
1671 enum loader_test_flags
1673 LOADER_EXPECTED_DECODER
= 0x1,
1674 LOADER_EXPECTED_CONVERTER
= 0x2,
1678 static void test_topology_loader(void)
1680 static const struct loader_test
1685 struct type_attr attrs
[8];
1689 struct type_attr attrs
[8];
1692 MF_CONNECT_METHOD method
;
1693 HRESULT expected_result
;
1699 /* PCM -> PCM, same type */
1703 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1704 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1705 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1706 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1707 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1708 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1713 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1714 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1715 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1716 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1717 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1718 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1727 /* PCM -> PCM, different bps. */
1731 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1732 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1733 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1734 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1735 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1736 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1741 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1742 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1743 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000 },
1744 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000 },
1745 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1746 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1751 MF_E_INVALIDMEDIATYPE
,
1755 /* PCM -> PCM, different bps. */
1759 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1760 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1761 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1762 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1763 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1764 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1769 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1770 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1771 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000 },
1772 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000 },
1773 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1774 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1778 MF_CONNECT_ALLOW_CONVERTER
,
1780 LOADER_EXPECTED_CONVERTER
| LOADER_TODO
,
1788 { &MF_MT_SUBTYPE
, WAVE_FORMAT_MPEGLAYER3
},
1789 { &MF_MT_AUDIO_NUM_CHANNELS
, 2 },
1790 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1791 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000 },
1792 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1797 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1798 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1799 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1800 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1801 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1802 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1807 MF_E_INVALIDMEDIATYPE
,
1815 { &MF_MT_SUBTYPE
, WAVE_FORMAT_MPEGLAYER3
},
1816 { &MF_MT_AUDIO_NUM_CHANNELS
, 2 },
1817 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1818 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000 },
1819 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1824 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1825 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1826 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1827 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1828 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1829 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1833 MF_CONNECT_ALLOW_CONVERTER
,
1834 MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION
,
1843 { &MF_MT_SUBTYPE
, WAVE_FORMAT_MPEGLAYER3
},
1844 { &MF_MT_AUDIO_NUM_CHANNELS
, 2 },
1845 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1846 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000 },
1847 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1852 { &MF_MT_SUBTYPE
, WAVE_FORMAT_PCM
},
1853 { &MF_MT_AUDIO_NUM_CHANNELS
, 1 },
1854 { &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100 },
1855 { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 },
1856 { &MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1 },
1857 { &MF_MT_AUDIO_BITS_PER_SAMPLE
, 8 },
1861 MF_CONNECT_ALLOW_DECODER
,
1863 LOADER_EXPECTED_DECODER
| LOADER_TODO
,
1867 IMFSampleGrabberSinkCallback test_grabber_callback
= { &test_grabber_callback_vtbl
};
1868 IMFTopologyNode
*src_node
, *sink_node
, *src_node2
, *sink_node2
, *mft_node
;
1869 IMFTopology
*topology
, *topology2
, *full_topology
;
1870 IMFMediaType
*media_type
, *input_type
, *output_type
;
1871 unsigned int i
, count
, value
, index
;
1872 IMFPresentationDescriptor
*pd
;
1873 IMFActivate
*sink_activate
;
1874 MF_TOPOLOGY_TYPE node_type
;
1875 IMFStreamDescriptor
*sd
;
1876 IMFTransform
*transform
;
1877 IMFMediaSource
*source
;
1878 IMFTopoLoader
*loader
;
1879 IUnknown
*node_object
;
1885 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1886 ok(hr
== S_OK
, "Startup failure, hr %#x.\n", hr
);
1888 hr
= MFCreateTopoLoader(NULL
);
1889 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
1891 hr
= MFCreateTopoLoader(&loader
);
1892 ok(hr
== S_OK
, "Failed to create topology loader, hr %#x.\n", hr
);
1894 hr
= MFCreateTopology(&topology
);
1895 ok(hr
== S_OK
, "Failed to create topology, hr %#x.\n", hr
);
1897 /* Empty topology */
1898 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
1900 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#x.\n", hr
);
1902 /* Add source node. */
1903 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
1904 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
1906 /* When a decoder is involved, windows requires this attribute to be present */
1907 source
= create_test_source();
1909 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
1910 ok(hr
== S_OK
, "Failed to set node source, hr %#x.\n", hr
);
1912 hr
= MFCreateMediaType(&media_type
);
1913 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
1915 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
1916 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1917 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
1918 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1920 hr
= MFCreateStreamDescriptor(0, 1, &media_type
, &sd
);
1921 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#x.\n", hr
);
1923 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
1924 ok(hr
== S_OK
, "Failed to set node sd, hr %#x.\n", hr
);
1926 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
1927 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#x.\n", hr
);
1929 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
1930 ok(hr
== S_OK
, "Failed to set node pd, hr %#x.\n", hr
);
1932 IMFPresentationDescriptor_Release(pd
);
1933 IMFStreamDescriptor_Release(sd
);
1934 IMFMediaType_Release(media_type
);
1936 hr
= IMFTopology_AddNode(topology
, src_node
);
1937 ok(hr
== S_OK
, "Failed to add a node, hr %#x.\n", hr
);
1939 /* Source node only. */
1940 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
1942 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#x.\n", hr
);
1944 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &sink_node
);
1945 ok(hr
== S_OK
, "Failed to create output node, hr %#x.\n", hr
);
1947 hr
= MFCreateMediaType(&media_type
);
1948 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
1950 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
1951 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1952 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
1953 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
1955 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &test_grabber_callback
, &sink_activate
);
1956 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#x.\n", hr
);
1958 hr
= IMFTopologyNode_SetObject(sink_node
, (IUnknown
*)sink_activate
);
1959 ok(hr
== S_OK
, "Failed to set object, hr %#x.\n", hr
);
1961 IMFMediaType_Release(media_type
);
1963 hr
= IMFTopology_AddNode(topology
, sink_node
);
1964 ok(hr
== S_OK
, "Failed to add sink node, hr %#x.\n", hr
);
1966 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
1968 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#x.\n", hr
);
1970 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, sink_node
, 0);
1971 ok(hr
== S_OK
, "Failed to connect nodes, hr %#x.\n", hr
);
1973 /* Sink was not resolved. */
1974 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
1975 ok(hr
== MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
, "Unexpected hr %#x.\n", hr
);
1977 hr
= MFCreateMediaType(&input_type
);
1978 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
1980 hr
= MFCreateMediaType(&output_type
);
1981 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
1983 for (i
= 0; i
< ARRAY_SIZE(loader_tests
); ++i
)
1985 const struct loader_test
*test
= &loader_tests
[i
];
1987 init_media_type(input_type
, test
->major
, test
->input_type
.attrs
);
1988 init_media_type(output_type
, test
->major
, test
->output_type
.attrs
);
1990 hr
= MFCreateSampleGrabberSinkActivate(output_type
, &test_grabber_callback
, &sink_activate
);
1991 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#x.\n", hr
);
1993 init_source_node(input_type
, source
, src_node
);
1994 init_sink_node(sink_activate
, test
->method
, sink_node
);
1996 hr
= IMFTopology_GetCount(topology
, &count
);
1997 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
1998 ok(!count
, "Unexpected count %u.\n", count
);
2000 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2001 todo_wine_if(test
->flags
& LOADER_TODO
)
2002 ok(hr
== test
->expected_result
, "Unexpected hr %#x on test %u.\n", hr
, i
);
2003 ok(full_topology
!= topology
, "Unexpected instance.\n");
2005 if (test
->expected_result
== S_OK
&& hr
== S_OK
)
2007 hr
= IMFTopology_GetCount(full_topology
, &count
);
2008 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
2010 ok(count
== 1, "Unexpected count %u.\n", count
);
2013 hr
= IMFTopology_GetUINT32(full_topology
, &MF_TOPOLOGY_RESOLUTION_STATUS
, &value
);
2015 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
2016 ok(value
== MF_TOPOLOGY_RESOLUTION_SUCCEEDED
, "Unexpected value %#x.\n", value
);
2019 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2021 if (test
->flags
& LOADER_EXPECTED_CONVERTER
)
2024 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2025 ok(hr
== S_OK
, "Failed to get node count, hr %#x.\n", hr
);
2026 todo_wine_if(test
->flags
& (LOADER_EXPECTED_CONVERTER
| LOADER_EXPECTED_DECODER
))
2027 ok(node_count
== count
, "Unexpected node count %u.\n", node_count
);
2029 hr
= IMFTopologyNode_GetTopoNodeID(src_node
, &node_id
);
2030 ok(hr
== S_OK
, "Failed to get source node id, hr %#x.\n", hr
);
2032 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &src_node2
);
2033 ok(hr
== S_OK
, "Failed to get source in resolved topology, hr %#x.\n", hr
);
2035 hr
= IMFTopologyNode_GetTopoNodeID(sink_node
, &node_id
);
2036 ok(hr
== S_OK
, "Failed to get sink node id, hr %#x.\n", hr
);
2038 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &sink_node2
);
2039 ok(hr
== S_OK
, "Failed to get sink in resolved topology, hr %#x.\n", hr
);
2041 if (test
->flags
& (LOADER_EXPECTED_DECODER
| LOADER_EXPECTED_CONVERTER
) && strcmp(winetest_platform
, "wine"))
2043 hr
= IMFTopologyNode_GetOutput(src_node2
, 0, &mft_node
, &index
);
2044 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#x.\n", hr
);
2045 ok(!index
, "Unexpected stream index %u.\n", index
);
2047 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2048 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#x.\n", hr
);
2049 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2051 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2052 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#x.\n", hr
);
2054 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2057 hr
= IMFTopologyNode_GetUINT32(mft_node
, &MF_TOPONODE_DECODER
, &value
);
2058 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
2059 ok(value
== 1, "Unexpected value.\n");
2062 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2063 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
2065 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void **)&transform
);
2066 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr
);
2067 IUnknown_Release(node_object
);
2069 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
2070 ok(hr
== S_OK
, "Failed to get transform input type, hr %#x.\n", hr
);
2072 hr
= IMFMediaType_Compare(input_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2073 ok(hr
== S_OK
, "Failed to compare media types, hr %#x.\n", hr
);
2074 ok(ret
, "Input type of first transform doesn't match source node type.\n");
2076 IMFTopologyNode_Release(mft_node
);
2077 IMFMediaType_Release(media_type
);
2078 IMFTransform_Release(transform
);
2080 hr
= IMFTopologyNode_GetInput(sink_node2
, 0, &mft_node
, &index
);
2081 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#x.\n", hr
);
2082 ok(!index
, "Unexpected stream index %u.\n", index
);
2084 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2085 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#x.\n", hr
);
2086 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2088 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2089 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
2091 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2092 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#x.\n", hr
);
2094 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void**) &transform
);
2095 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr
);
2096 IUnknown_Release(node_object
);
2098 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
2099 ok(hr
== S_OK
, "Failed to get transform output type, hr %#x.\n", hr
);
2101 hr
= IMFMediaType_Compare(output_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2102 ok(hr
== S_OK
, "Failed to compare media types, hr %#x.\n", hr
);
2103 ok(ret
, "Output type of last transform doesn't match sink node type.\n");
2105 IMFTopologyNode_Release(mft_node
);
2106 IMFMediaType_Release(media_type
);
2107 IMFTransform_Release(transform
);
2110 IMFTopologyNode_Release(sink_node2
);
2112 hr
= IMFTopology_SetUINT32(full_topology
, &IID_IMFTopology
, 123);
2113 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2114 hr
= IMFTopoLoader_Load(loader
, full_topology
, &topology2
, NULL
);
2115 ok(hr
== S_OK
, "Failed to resolve topology, hr %#x.\n", hr
);
2116 ok(full_topology
!= topology2
, "Unexpected instance.\n");
2117 hr
= IMFTopology_GetUINT32(topology2
, &IID_IMFTopology
, &value
);
2118 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2120 IMFTopology_Release(topology2
);
2121 IMFTopology_Release(full_topology
);
2124 hr
= IMFTopology_GetCount(topology
, &count
);
2125 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
2126 ok(!count
, "Unexpected count %u.\n", count
);
2128 IMFActivate_ShutdownObject(sink_activate
);
2129 IMFActivate_Release(sink_activate
);
2132 IMFMediaType_Release(input_type
);
2133 IMFMediaType_Release(output_type
);
2135 IMFMediaSource_Release(source
);
2136 IMFTopoLoader_Release(loader
);
2139 ok(hr
== S_OK
, "Shutdown failure, hr %#x.\n", hr
);
2142 static void test_topology_loader_evr(void)
2144 IMFTopologyNode
*node
, *source_node
, *evr_node
;
2145 IMFTopology
*topology
, *full_topology
;
2146 IMFMediaTypeHandler
*handler
;
2147 unsigned int i
, count
, value
;
2148 IMFStreamSink
*stream_sink
;
2149 IMFMediaType
*media_type
;
2150 IMFActivate
*activate
;
2151 IMFTopoLoader
*loader
;
2158 hr
= CoInitialize(NULL
);
2159 ok(hr
== S_OK
, "Failed to initialize, hr %#x.\n", hr
);
2161 hr
= MFCreateTopoLoader(&loader
);
2162 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2165 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &source_node
);
2166 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
2168 hr
= MFCreateMediaType(&media_type
);
2169 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
2171 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
2172 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2173 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
2174 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2175 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
2176 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2177 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
2178 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2180 init_source_node(media_type
, NULL
, source_node
);
2182 /* EVR sink node. */
2183 window
= create_window();
2185 hr
= MFCreateVideoRendererActivate(window
, &activate
);
2186 ok(hr
== S_OK
, "Failed to create activate object, hr %#x.\n", hr
);
2188 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2189 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2191 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
2192 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2194 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &evr_node
);
2195 ok(hr
== S_OK
, "Failed to create topology node, hr %#x.\n", hr
);
2197 hr
= IMFTopologyNode_SetObject(evr_node
, (IUnknown
*)stream_sink
);
2198 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2200 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
2201 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2202 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
2203 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2204 IMFMediaTypeHandler_Release(handler
);
2206 IMFStreamSink_Release(stream_sink
);
2207 IMFMediaSink_Release(sink
);
2209 hr
= MFCreateTopology(&topology
);
2210 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2212 hr
= IMFTopology_AddNode(topology
, source_node
);
2213 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2214 hr
= IMFTopology_AddNode(topology
, evr_node
);
2215 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2216 hr
= IMFTopologyNode_ConnectOutput(source_node
, 0, evr_node
, 0);
2217 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2219 hr
= IMFTopologyNode_SetUINT32(evr_node
, &MF_TOPONODE_CONNECT_METHOD
, MF_CONNECT_DIRECT
);
2220 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2222 hr
= IMFTopologyNode_GetCount(evr_node
, &count
);
2223 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2224 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
2226 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2227 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2229 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2230 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2231 ok(node_count
== 3, "Unexpected node count %u.\n", node_count
);
2233 for (i
= 0; i
< node_count
; ++i
)
2235 MF_TOPOLOGY_TYPE node_type
;
2237 hr
= IMFTopology_GetNode(full_topology
, i
, &node
);
2238 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2240 hr
= IMFTopologyNode_GetNodeType(node
, &node_type
);
2241 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2243 if (node_type
== MF_TOPOLOGY_OUTPUT_NODE
)
2246 hr
= IMFTopologyNode_GetUINT32(node
, &MF_TOPONODE_STREAMID
, &value
);
2247 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2248 ok(!value
, "Unexpected stream id %u.\n", value
);
2250 else if (node_type
== MF_TOPOLOGY_SOURCESTREAM_NODE
)
2253 hr
= IMFTopologyNode_GetUINT64(node
, &MF_TOPONODE_MEDIASTART
, &value64
);
2254 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2255 ok(!value64
, "Unexpected value.\n");
2259 IMFTopology_Release(full_topology
);
2261 IMFTopoLoader_Release(loader
);
2263 IMFTopologyNode_Release(source_node
);
2264 IMFTopologyNode_Release(evr_node
);
2265 IMFTopology_Release(topology
);
2266 IMFMediaType_Release(media_type
);
2267 DestroyWindow(window
);
2272 static HRESULT WINAPI
testshutdown_QueryInterface(IMFShutdown
*iface
, REFIID riid
, void **obj
)
2274 if (IsEqualIID(riid
, &IID_IMFShutdown
) ||
2275 IsEqualIID(riid
, &IID_IUnknown
))
2278 IMFShutdown_AddRef(iface
);
2283 return E_NOINTERFACE
;
2286 static ULONG WINAPI
testshutdown_AddRef(IMFShutdown
*iface
)
2291 static ULONG WINAPI
testshutdown_Release(IMFShutdown
*iface
)
2296 static HRESULT WINAPI
testshutdown_Shutdown(IMFShutdown
*iface
)
2301 static HRESULT WINAPI
testshutdown_GetShutdownStatus(IMFShutdown
*iface
, MFSHUTDOWN_STATUS
*status
)
2303 ok(0, "Unexpected call.\n");
2307 static const IMFShutdownVtbl testshutdownvtbl
=
2309 testshutdown_QueryInterface
,
2310 testshutdown_AddRef
,
2311 testshutdown_Release
,
2312 testshutdown_Shutdown
,
2313 testshutdown_GetShutdownStatus
,
2316 static void test_MFShutdownObject(void)
2318 IMFShutdown testshutdown
= { &testshutdownvtbl
};
2319 IUnknown testshutdown2
= { &testservicevtbl
};
2322 hr
= MFShutdownObject(NULL
);
2323 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2325 hr
= MFShutdownObject((IUnknown
*)&testshutdown
);
2326 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
2328 hr
= MFShutdownObject(&testshutdown2
);
2329 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
2339 static HRESULT WINAPI
test_clock_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **obj
)
2341 if (IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2342 IsEqualIID(riid
, &IID_IUnknown
))
2345 IMFClockStateSink_AddRef(iface
);
2350 return E_NOINTERFACE
;
2353 static ULONG WINAPI
test_clock_sink_AddRef(IMFClockStateSink
*iface
)
2358 static ULONG WINAPI
test_clock_sink_Release(IMFClockStateSink
*iface
)
2363 static HRESULT WINAPI
test_clock_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
, LONGLONG offset
)
2368 static HRESULT WINAPI
test_clock_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
2373 static HRESULT WINAPI
test_clock_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
2378 static HRESULT WINAPI
test_clock_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
2383 static HRESULT WINAPI
test_clock_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
2388 static const IMFClockStateSinkVtbl test_clock_sink_vtbl
=
2390 test_clock_sink_QueryInterface
,
2391 test_clock_sink_AddRef
,
2392 test_clock_sink_Release
,
2393 test_clock_sink_OnClockStart
,
2394 test_clock_sink_OnClockStop
,
2395 test_clock_sink_OnClockPause
,
2396 test_clock_sink_OnClockRestart
,
2397 test_clock_sink_OnClockSetRate
,
2400 static void test_presentation_clock(void)
2402 static const struct clock_state_test
2404 enum clock_action action
;
2405 MFCLOCK_STATE clock_state
;
2406 MFCLOCK_STATE source_state
;
2409 clock_state_change
[] =
2411 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
},
2412 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_INVALIDREQUEST
},
2413 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_CLOCK_STATE_ALREADY_SET
},
2414 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2415 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2416 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2417 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2418 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2419 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2420 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2421 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2422 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_INVALIDREQUEST
},
2423 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2424 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2425 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2427 IMFClockStateSink test_sink
= { &test_clock_sink_vtbl
};
2428 IMFPresentationTimeSource
*time_source
;
2429 MFCLOCK_PROPERTIES props
, props2
;
2430 IMFRateControl
*rate_control
;
2431 IMFPresentationClock
*clock
;
2432 MFSHUTDOWN_STATUS status
;
2433 IMFShutdown
*shutdown
;
2434 MFTIME systime
, time
;
2435 LONGLONG clock_time
;
2436 MFCLOCK_STATE state
;
2443 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2444 ok(hr
== S_OK
, "Failed to start up, hr %#x.\n", hr
);
2446 hr
= MFCreatePresentationClock(&clock
);
2447 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#x.\n", hr
);
2449 check_interface(clock
, &IID_IMFTimer
, TRUE
);
2450 check_interface(clock
, &IID_IMFRateControl
, TRUE
);
2451 check_interface(clock
, &IID_IMFPresentationClock
, TRUE
);
2452 check_interface(clock
, &IID_IMFShutdown
, TRUE
);
2453 check_interface(clock
, &IID_IMFClock
, TRUE
);
2455 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&rate_control
);
2456 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#x.\n", hr
);
2458 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2459 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2461 hr
= IMFPresentationClock_GetTimeSource(clock
, NULL
);
2462 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2464 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2465 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2467 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, NULL
);
2468 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2470 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2471 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2473 hr
= IMFPresentationClock_GetTime(clock
, NULL
);
2474 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
2477 hr
= IMFPresentationClock_GetContinuityKey(clock
, &value
);
2478 ok(hr
== S_OK
, "Failed to get continuity key, hr %#x.\n", hr
);
2479 ok(value
== 0, "Unexpected value %u.\n", value
);
2481 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2482 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2484 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2485 ok(hr
== S_OK
, "Failed to get state, hr %#x.\n", hr
);
2486 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2488 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &clock_time
, &systime
);
2489 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2491 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, NULL
, &systime
);
2492 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2494 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, NULL
);
2495 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2498 hr
= IMFPresentationClock_AddClockStateSink(clock
, NULL
);
2499 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2501 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2502 ok(hr
== S_OK
, "Failed to add a sink, hr %#x.\n", hr
);
2504 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2505 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2507 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, NULL
);
2508 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2510 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2511 ok(hr
== S_OK
, "Failed to remove sink, hr %#x.\n", hr
);
2513 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2514 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2516 /* State change commands, time source is not set yet. */
2517 hr
= IMFPresentationClock_Start(clock
, 0);
2518 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2520 hr
= IMFPresentationClock_Pause(clock
);
2521 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2523 hr
= IMFPresentationClock_Stop(clock
);
2524 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2526 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2527 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
2529 /* Set default time source. */
2530 hr
= MFCreateSystemTimeSource(&time_source
);
2531 ok(hr
== S_OK
, "Failed to create time source, hr %#x.\n", hr
);
2533 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &value
);
2534 ok(hr
== S_OK
, "Failed to get time source flags, hr %#x.\n", hr
);
2535 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2536 "Unexpected clock flags %#x.\n", value
);
2538 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
2539 ok(hr
== S_OK
, "Failed to set time source, hr %#x.\n", hr
);
2541 hr
= IMFPresentationTimeSource_GetProperties(time_source
, &props2
);
2542 ok(hr
== S_OK
, "Failed to get time source properties, hr %#x.\n", hr
);
2544 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2545 ok(hr
== S_OK
, "Failed to get clock flags, hr %#x.\n", hr
);
2546 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2547 "Unexpected clock flags %#x.\n", value
);
2549 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2550 ok(hr
== S_OK
, "Failed to get clock properties, hr %#x.\n", hr
);
2551 ok(!memcmp(&props
, &props2
, sizeof(props
)), "Unexpected clock properties.\n");
2553 /* State changes. */
2554 for (i
= 0; i
< ARRAY_SIZE(clock_state_change
); ++i
)
2556 switch (clock_state_change
[i
].action
)
2559 hr
= IMFPresentationClock_Stop(clock
);
2562 hr
= IMFPresentationClock_Pause(clock
);
2565 hr
= IMFPresentationClock_Start(clock
, 0);
2570 ok(hr
== clock_state_change
[i
].hr
, "%u: unexpected hr %#x.\n", i
, hr
);
2572 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
2573 ok(hr
== S_OK
, "%u: failed to get state, hr %#x.\n", i
, hr
);
2574 ok(state
== clock_state_change
[i
].source_state
, "%u: unexpected state %d.\n", i
, state
);
2576 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2577 ok(hr
== S_OK
, "%u: failed to get state, hr %#x.\n", i
, hr
);
2578 ok(state
== clock_state_change
[i
].clock_state
, "%u: unexpected state %d.\n", i
, state
);
2581 /* Clock time stamps. */
2582 hr
= IMFPresentationClock_Start(clock
, 10);
2583 ok(hr
== S_OK
, "Failed to start presentation clock, hr %#x.\n", hr
);
2585 hr
= IMFPresentationClock_Pause(clock
);
2586 ok(hr
== S_OK
, "Failed to pause presentation clock, hr %#x.\n", hr
);
2588 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2589 ok(hr
== S_OK
, "Failed to get clock time, hr %#x.\n", hr
);
2591 hr
= IMFPresentationTimeSource_GetCorrelatedTime(time_source
, 0, &clock_time
, &systime
);
2592 ok(hr
== S_OK
, "Failed to get time source time, hr %#x.\n", hr
);
2593 ok(time
== clock_time
, "Unexpected clock time.\n");
2595 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, &systime
);
2596 ok(hr
== S_OK
, "Failed to get clock time, hr %#x.\n", hr
);
2597 ok(time
== clock_time
, "Unexpected clock time.\n");
2599 IMFPresentationTimeSource_Release(time_source
);
2601 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
2602 ok(hr
== S_OK
, "Failed to get clock rate, hr %#x.\n", hr
);
2604 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
2605 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2607 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2608 ok(hr
== S_OK
, "Failed to get clock rate, hr %#x.\n", hr
);
2609 ok(rate
== 1.0f
, "Unexpected rate.\n");
2610 ok(!thin
, "Unexpected thinning.\n");
2612 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2613 ok(hr
== S_OK
, "Failed to get clock state, hr %#x.\n", hr
);
2614 ok(state
== MFCLOCK_STATE_PAUSED
, "Unexpected state %d.\n", state
);
2616 hr
= IMFPresentationClock_Start(clock
, 0);
2617 ok(hr
== S_OK
, "Failed to stop, hr %#x.\n", hr
);
2619 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2620 ok(hr
== S_OK
, "Failed to set clock rate, hr %#x.\n", hr
);
2621 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2622 ok(hr
== S_OK
, "Failed to get clock rate, hr %#x.\n", hr
);
2623 ok(rate
== 0.0f
, "Unexpected rate.\n");
2624 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2625 ok(hr
== S_OK
, "Failed to set clock rate, hr %#x.\n", hr
);
2626 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2627 ok(hr
== S_OK
, "Failed to set clock rate, hr %#x.\n", hr
);
2628 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.5f
);
2629 ok(hr
== S_OK
, "Failed to set clock rate, hr %#x.\n", hr
);
2630 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, -1.0f
);
2631 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#x.\n", hr
);
2633 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2634 ok(hr
== S_OK
, "Failed to get clock state, hr %#x.\n", hr
);
2635 ok(state
== MFCLOCK_STATE_RUNNING
, "Unexpected state %d.\n", state
);
2637 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2638 ok(hr
== S_OK
, "Failed to get clock rate, hr %#x.\n", hr
);
2639 ok(rate
== 0.5f
, "Unexpected rate.\n");
2640 ok(!thin
, "Unexpected thinning.\n");
2642 IMFRateControl_Release(rate_control
);
2644 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
2645 ok(hr
== S_OK
, "Failed to get shutdown interface, hr %#x.\n", hr
);
2647 /* Shutdown behavior. */
2648 hr
= IMFShutdown_GetShutdownStatus(shutdown
, NULL
);
2649 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
2651 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2652 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#x.\n", hr
);
2654 hr
= IMFShutdown_Shutdown(shutdown
);
2655 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
2658 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2659 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2660 ok(!!time_source
, "Unexpected instance %p.\n", time_source
);
2661 IMFPresentationTimeSource_Release(time_source
);
2663 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2664 ok(hr
== S_OK
, "Failed to get time, hr %#x.\n", hr
);
2666 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2667 ok(hr
== S_OK
, "Failed to get status, hr %#x.\n", hr
);
2668 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2670 hr
= IMFPresentationClock_Start(clock
, 0);
2671 ok(hr
== S_OK
, "Failed to start the clock, hr %#x.\n", hr
);
2673 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2674 ok(hr
== S_OK
, "Failed to get status, hr %#x.\n", hr
);
2675 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2677 hr
= IMFShutdown_Shutdown(shutdown
);
2678 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2680 IMFShutdown_Release(shutdown
);
2682 IMFPresentationClock_Release(clock
);
2685 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
2688 static HRESULT WINAPI
grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
, void **obj
)
2690 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
2691 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2692 IsEqualIID(riid
, &IID_IUnknown
))
2695 IMFSampleGrabberSinkCallback_AddRef(iface
);
2700 return E_NOINTERFACE
;
2703 static ULONG WINAPI
grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
2708 static ULONG WINAPI
grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
2713 static HRESULT WINAPI
grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, LONGLONG offset
)
2718 static HRESULT WINAPI
grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2723 static HRESULT WINAPI
grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2728 static HRESULT WINAPI
grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2733 static HRESULT WINAPI
grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, float rate
)
2738 static HRESULT WINAPI
grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
2739 IMFPresentationClock
*clock
)
2744 static HRESULT WINAPI
grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
2745 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
2750 static HRESULT WINAPI
grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
2755 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl
=
2757 grabber_callback_QueryInterface
,
2758 grabber_callback_AddRef
,
2759 grabber_callback_Release
,
2760 grabber_callback_OnClockStart
,
2761 grabber_callback_OnClockStop
,
2762 grabber_callback_OnClockPause
,
2763 grabber_callback_OnClockRestart
,
2764 grabber_callback_OnClockSetRate
,
2765 grabber_callback_OnSetPresentationClock
,
2766 grabber_callback_OnProcessSample
,
2767 grabber_callback_OnShutdown
,
2770 static IMFSampleGrabberSinkCallback grabber_callback
= { &grabber_callback_vtbl
};
2772 static void test_sample_grabber(void)
2774 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
2775 IMFMediaTypeHandler
*handler
, *handler2
;
2776 IMFPresentationTimeSource
*time_source
;
2777 IMFPresentationClock
*clock
, *clock2
;
2778 IMFStreamSink
*stream
, *stream2
;
2779 IMFRateSupport
*rate_support
;
2780 IMFMediaEventGenerator
*eg
;
2781 IMFMediaSink
*sink
, *sink2
;
2782 DWORD flags
, count
, id
;
2783 IMFActivate
*activate
;
2784 IMFMediaEvent
*event
;
2791 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2792 ok(hr
== S_OK
, "Failed to start up, hr %#x.\n", hr
);
2794 hr
= MFCreateMediaType(&media_type
);
2795 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
2797 hr
= MFCreateSampleGrabberSinkActivate(NULL
, NULL
, &activate
);
2798 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
2800 hr
= MFCreateSampleGrabberSinkActivate(NULL
, &grabber_callback
, &activate
);
2801 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
2803 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2804 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
2805 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2806 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
2808 EXPECT_REF(media_type
, 1);
2809 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
2810 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#x.\n", hr
);
2811 EXPECT_REF(media_type
, 2);
2813 hr
= IMFActivate_GetCount(activate
, &count
);
2814 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
2815 ok(!count
, "Unexpected count %u.\n", count
);
2817 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2818 ok(hr
== S_OK
, "Failed to activate object, hr %#x.\n", hr
);
2820 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
2821 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
2822 check_interface(sink
, &IID_IMFGetService
, TRUE
);
2823 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
2824 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
2826 if (SUCCEEDED(MFGetService((IUnknown
*)sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
)))
2828 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
2829 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2830 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
2832 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
2833 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2834 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
2836 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
2837 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2838 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
2840 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
2841 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2842 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
2844 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
2845 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2846 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2848 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
2849 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2850 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2852 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
2853 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2854 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2856 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
2857 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2858 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2860 hr
= IMFRateSupport_IsRateSupported(rate_support
, TRUE
, 1.0f
, &rate
);
2861 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
2862 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
2864 IMFRateSupport_Release(rate_support
);
2867 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
2868 ok(hr
== S_OK
, "Failed to get sink flags, hr %#x.\n", hr
);
2869 ok(flags
& MEDIASINK_FIXED_STREAMS
, "Unexpected flags %#x.\n", flags
);
2871 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
2872 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
2873 ok(count
== 1, "Unexpected stream count %u.\n", count
);
2875 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
2876 ok(hr
== S_OK
, "Failed to get sink stream, hr %#x.\n", hr
);
2878 check_interface(stream
, &IID_IMFMediaEventGenerator
, TRUE
);
2879 check_interface(stream
, &IID_IMFMediaTypeHandler
, TRUE
);
2881 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
2882 ok(hr
== S_OK
, "Failed to get stream id, hr %#x.\n", hr
);
2883 ok(id
== 0, "Unexpected id %#x.\n", id
);
2885 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
2886 ok(hr
== S_OK
, "Failed to get media sink, hr %x.\n", hr
);
2887 ok(sink2
== sink
, "Unexpected sink.\n");
2888 IMFMediaSink_Release(sink2
);
2890 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 1, &stream2
);
2891 ok(hr
== MF_E_INVALIDINDEX
, "Unexpected hr %#x.\n", hr
);
2893 hr
= IMFMediaSink_GetStreamSinkById(sink
, 1, &stream2
);
2894 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
2896 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
2897 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#x.\n", hr
);
2899 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
2900 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#x.\n", hr
);
2902 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
2903 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#x.\n", hr
);
2905 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
2907 /* Event generator. */
2908 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFMediaEventGenerator
, (void **)&eg
);
2909 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
2911 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
2912 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#x.\n", hr
);
2914 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&unk
);
2915 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#x.\n", hr
);
2917 hr
= IMFStreamSink_QueryInterface(stream
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
2918 ok(hr
== S_OK
, "Failed to get handler interface, hr %#x.\n", hr
);
2920 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
2921 ok(hr
== S_OK
, "Failed to get type handler, hr %#x.\n", hr
);
2922 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
2923 ok(hr
== S_OK
, "Failed to get media type count, hr %#x.\n", hr
);
2924 ok(count
== 0, "Unexpected count %u.\n", count
);
2925 ok(handler
== handler2
, "Unexpected handler.\n");
2927 IMFMediaTypeHandler_Release(handler
);
2928 IMFMediaTypeHandler_Release(handler2
);
2931 hr
= MFCreatePresentationClock(&clock
);
2932 ok(hr
== S_OK
, "Failed to create clock object, hr %#x.\n", hr
);
2934 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
2935 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
2937 hr
= IMFMediaSink_GetPresentationClock(sink
, &clock2
);
2938 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#x.\n", hr
);
2940 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
2941 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#x.\n", hr
);
2943 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
2944 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#x.\n", hr
);
2946 hr
= MFCreateSystemTimeSource(&time_source
);
2947 ok(hr
== S_OK
, "Failed to create time source, hr %#x.\n", hr
);
2949 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
2950 ok(hr
== S_OK
, "Failed to set time source, hr %#x.\n", hr
);
2951 IMFPresentationTimeSource_Release(time_source
);
2953 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
2954 ok(hr
== S_OK
, "Failed to get sink flags, hr %#x.\n", hr
);
2956 hr
= IMFActivate_ShutdownObject(activate
);
2957 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
2959 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
2960 ok(hr
== S_OK
, "Failed to get sink flags, hr %#x.\n", hr
);
2962 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
2963 ok(hr
== S_OK
, "Failed to get type handler, hr %#x.\n", hr
);
2965 /* On Win8+ this initialization happens automatically. */
2966 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
2967 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
2969 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
2970 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
2972 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
2973 ok(hr
== S_OK
, "Failed to get media type count, hr %#x.\n", hr
);
2974 ok(count
== 0, "Unexpected count %u.\n", count
);
2976 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
2977 ok(hr
== S_OK
, "Failed to get major type, hr %#x.\n", hr
);
2978 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid
));
2980 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
2981 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
2982 ok(media_type2
== media_type
, "Unexpected media type.\n");
2983 IMFMediaType_Release(media_type2
);
2985 hr
= MFCreateMediaType(&media_type2
);
2986 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
2988 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
2989 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
2991 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2992 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
2994 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
2995 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
2997 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_Float
);
2998 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3000 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3001 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3003 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3004 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3006 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3007 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3009 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3010 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
3011 IMFMediaType_Release(media_type
);
3013 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3014 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3016 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3017 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
3018 ok(media_type2
== media_type
, "Unexpected media type.\n");
3019 IMFMediaType_Release(media_type
);
3021 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3022 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
3024 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, NULL
);
3025 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3027 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3028 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3030 hr
= MFCreateMediaType(&media_type
);
3031 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3033 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3034 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3036 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
3037 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3039 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3040 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3042 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3043 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3045 media_type3
= (void *)0xdeadbeef;
3046 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3047 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3048 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3050 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_FIXED_SIZE_SAMPLES
, 1);
3051 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3053 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_SAMPLE_SIZE
, 1024);
3054 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3056 media_type3
= (void *)0xdeadbeef;
3057 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3058 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3059 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3061 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3062 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3064 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3065 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#x.\n", hr
);
3067 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3068 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#x.\n", hr
);
3070 EXPECT_REF(clock
, 3);
3071 hr
= IMFMediaSink_Shutdown(sink
);
3072 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
3073 EXPECT_REF(clock
, 1);
3075 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3076 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3078 hr
= IMFMediaSink_Shutdown(sink
);
3079 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3081 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3082 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3084 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3085 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3087 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3088 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3090 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream2
);
3091 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3093 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3094 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3096 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3097 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3100 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3101 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3102 ok(id
== 1, "Unexpected id %u.\n", id
);
3104 media_type3
= (void *)0xdeadbeef;
3105 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3106 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3107 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3109 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3110 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3112 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3113 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3115 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3116 ok(hr
== S_OK
, "Failed to get type count, hr %#x.\n", hr
);
3118 IMFMediaType_Release(media_type2
);
3119 IMFMediaType_Release(media_type
);
3121 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3122 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
3124 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3125 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3127 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
3128 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3130 hr
= IMFMediaTypeHandler_GetMajorType(handler
, NULL
);
3131 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3133 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3134 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3136 IMFMediaTypeHandler_Release(handler
);
3138 handler
= (void *)0xdeadbeef;
3139 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3140 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#x.\n", hr
);
3141 ok(handler
== (void *)0xdeadbeef, "Unexpected pointer.\n");
3143 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, NULL
);
3144 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3146 IMFMediaEventGenerator_Release(eg
);
3147 IMFMediaSink_Release(sink
);
3148 IMFStreamSink_Release(stream
);
3150 refcount
= IMFActivate_Release(activate
);
3151 ok(!refcount
, "Unexpected refcount %u.\n", refcount
);
3153 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
3154 hr
= MFCreateMediaType(&media_type
);
3155 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3157 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3158 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3159 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3160 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3162 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3163 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#x.\n", hr
);
3165 hr
= IMFActivate_SetUINT32(activate
, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
, 1);
3166 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3168 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3169 ok(hr
== S_OK
, "Failed to activate object, hr %#x.\n", hr
);
3171 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3172 ok(hr
== S_OK
, "Failed to get sink flags, hr %#x.\n", hr
);
3173 ok(flags
& MEDIASINK_RATELESS
, "Unexpected flags %#x.\n", flags
);
3175 hr
= IMFActivate_ShutdownObject(activate
);
3176 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
3178 hr
= IMFMediaSink_Shutdown(sink
);
3179 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
3181 IMFMediaSink_Release(sink
);
3184 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3185 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#x.\n", hr
);
3187 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3188 ok(hr
== S_OK
, "Failed to activate object, hr %#x.\n", hr
);
3189 IMFMediaSink_Release(sink
);
3191 hr
= IMFActivate_ShutdownObject(activate
);
3192 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
3194 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3195 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3197 hr
= IMFActivate_GetCount(activate
, &count
);
3198 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3200 hr
= IMFActivate_DetachObject(activate
);
3201 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3203 IMFActivate_Release(activate
);
3205 IMFMediaType_Release(media_type
);
3206 IMFPresentationClock_Release(clock
);
3209 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
3212 static void test_sample_grabber_is_mediatype_supported(void)
3214 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
3215 IMFMediaTypeHandler
*handler
;
3216 IMFActivate
*activate
;
3217 IMFStreamSink
*stream
;
3223 /* IsMediaTypeSupported checks are done against the creation type, and check format data */
3224 hr
= MFCreateMediaType(&media_type
);
3225 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3227 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3228 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3229 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3230 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3231 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3232 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3234 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3235 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#x.\n", hr
);
3237 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3238 ok(hr
== S_OK
, "Failed to activate object, hr %#x.\n", hr
);
3240 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3241 ok(hr
== S_OK
, "Failed to get sink stream, hr %#x.\n", hr
);
3242 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3243 ok(hr
== S_OK
, "Failed to get type handler, hr %#x.\n", hr
);
3244 IMFStreamSink_Release(stream
);
3246 IMFMediaSink_Release(sink
);
3248 /* On Win8+ this initialization happens automatically. */
3249 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3250 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
3252 hr
= MFCreateMediaType(&media_type2
);
3253 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3255 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3256 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3257 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3258 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3259 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3260 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3262 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3263 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3265 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3266 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Failed to set media type, hr %#x.\n", hr
);
3268 /* Make it match grabber type sample rate. */
3269 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3270 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3272 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3273 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3275 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3276 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
3277 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type3
);
3278 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
3279 ok(media_type3
== media_type2
, "Unexpected media type instance.\n");
3280 IMFMediaType_Release(media_type3
);
3282 /* Change original type. */
3283 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3284 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3286 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3287 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3289 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3290 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3292 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3293 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3295 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3296 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3297 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3299 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3300 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3302 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3303 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3304 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3306 IMFMediaType_Release(media_type2
);
3307 IMFMediaType_Release(media_type
);
3309 IMFMediaTypeHandler_Release(handler
);
3311 refcount
= IMFActivate_Release(activate
);
3312 ok(!refcount
, "Unexpected refcount %u.\n", refcount
);
3315 static BOOL
is_supported_video_type(const GUID
*guid
)
3317 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
3318 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
3319 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
3320 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
3321 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
3322 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
3323 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
3324 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
3325 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
3326 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
3327 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
3328 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
3329 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
3330 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
3331 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
3332 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
3333 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
3334 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
3335 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
3336 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
3337 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
3338 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
3339 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
3340 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
3341 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
3342 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
3343 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
3344 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
3345 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
3346 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
3349 static void test_video_processor(void)
3351 DWORD input_count
, output_count
, input_id
, output_id
, flags
;
3352 DWORD input_min
, input_max
, output_min
, output_max
, i
, count
;
3353 IMFAttributes
*attributes
, *attributes2
;
3354 IMFMediaType
*media_type
, *media_type2
;
3355 MFT_OUTPUT_DATA_BUFFER output_buffer
;
3356 MFT_OUTPUT_STREAM_INFO output_info
;
3357 MFT_INPUT_STREAM_INFO input_info
;
3358 IMFSample
*sample
, *sample2
;
3359 IMFTransform
*transform
;
3360 IMFMediaBuffer
*buffer
;
3361 IMFMediaEvent
*event
;
3366 hr
= CoInitialize(NULL
);
3367 ok(hr
== S_OK
, "Failed to initialize, hr %#x.\n", hr
);
3369 hr
= CoCreateInstance(&CLSID_VideoProcessorMFT
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
3370 (void **)&transform
);
3373 skip("Failed to create Video Processor instance, skipping tests.\n");
3378 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
3380 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
3381 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
3382 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
3384 /* Transform global attributes. */
3385 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3386 ok(hr
== S_OK
, "Failed to get attributes, hr %#x.\n", hr
);
3388 hr
= IMFAttributes_GetCount(attributes
, &count
);
3389 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3391 ok(!!count
, "Unexpected attribute count %u.\n", count
);
3394 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D11_AWARE
, &value
);
3396 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3397 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
3399 hr
= IMFTransform_GetAttributes(transform
, &attributes2
);
3400 ok(hr
== S_OK
, "Failed to get attributes, hr %#x.\n", hr
);
3401 ok(attributes
== attributes2
, "Unexpected instance.\n");
3402 IMFAttributes_Release(attributes
);
3403 IMFAttributes_Release(attributes2
);
3405 hr
= IMFTransform_GetStreamLimits(transform
, &input_min
, &input_max
, &output_min
, &output_max
);
3406 ok(hr
== S_OK
, "Failed to get stream limits, hr %#x.\n", hr
);
3407 ok(input_min
== input_max
&& input_min
== 1 && output_min
== output_max
&& output_min
== 1,
3408 "Unexpected stream limits.\n");
3410 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
3411 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
3412 ok(input_count
== 1 && output_count
== 1, "Unexpected stream count %u, %u.\n", input_count
, output_count
);
3414 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
3415 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3418 hr
= IMFTransform_AddInputStreams(transform
, 1, &input_id
);
3419 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3421 hr
= IMFTransform_DeleteInputStream(transform
, 0);
3422 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3424 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3426 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
3428 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
3429 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3431 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
3433 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
3435 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
3436 ok(hr
== S_OK
, "Failed to get output attributes, hr %#x.\n", hr
);
3437 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes2
);
3438 ok(hr
== S_OK
, "Failed to get output attributes, hr %#x.\n", hr
);
3439 ok(attributes
== attributes2
, "Unexpected instance.\n");
3440 IMFAttributes_Release(attributes
);
3441 IMFAttributes_Release(attributes2
);
3443 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3445 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
3447 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
3449 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
3451 hr
= IMFTransform_GetInputCurrentType(transform
, 1, &media_type
);
3453 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
3455 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
3457 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
3459 hr
= IMFTransform_GetOutputCurrentType(transform
, 1, &media_type
);
3461 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
3463 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
3465 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
3467 memset(&input_info
, 0xcc, sizeof(input_info
));
3468 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3470 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
3471 ok(input_info
.dwFlags
== 0, "Unexpected flag %#x.\n", input_info
.dwFlags
);
3472 ok(input_info
.cbSize
== 0, "Unexpected size %u.\n", input_info
.cbSize
);
3473 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %u.\n", input_info
.cbMaxLookahead
);
3474 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %u.\n", input_info
.cbAlignment
);
3476 hr
= MFCreateMediaEvent(MEUnknown
, &GUID_NULL
, S_OK
, NULL
, &event
);
3477 ok(hr
== S_OK
, "Failed to create event object, hr %#x.\n", hr
);
3478 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
3479 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3480 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
3481 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
3482 IMFMediaEvent_Release(event
);
3484 /* Configure stream types. */
3487 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
3490 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
3494 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
3495 ok(hr
== S_OK
, "Failed to get available type, hr %#x.\n", hr
);
3496 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3497 IMFMediaType_Release(media_type2
);
3499 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
3500 ok(hr
== S_OK
, "Failed to get major type, hr %#x.\n", hr
);
3501 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
3503 hr
= IMFMediaType_GetCount(media_type
, &count
);
3504 ok(hr
== S_OK
, "Failed to get attributes count, hr %#x.\n", hr
);
3505 ok(count
== 2, "Unexpected count %u.\n", count
);
3507 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
3508 ok(hr
== S_OK
, "Failed to get subtype, hr %#x.\n", hr
);
3509 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
3511 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3512 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
3514 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3515 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
3517 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
3518 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
3520 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
3521 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
3522 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
3523 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
3525 IMFMediaType_Release(media_type
);
3529 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3530 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3532 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3533 ok(hr
== S_OK
, "Failed to test input type %s, hr %#x.\n", wine_dbgstr_guid(&guid
), hr
);
3535 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3536 ok(hr
== S_OK
, "Failed to test input type, hr %#x.\n", hr
);
3538 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
3539 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
3540 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3541 IMFMediaType_Release(media_type2
);
3543 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3544 ok(hr
== S_OK
, "Failed to get input status, hr %#x.\n", hr
);
3545 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#x.\n", flags
);
3547 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3548 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
3549 ok(input_info
.dwFlags
== 0, "Unexpected flags %#x.\n", input_info
.dwFlags
);
3550 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %u.\n", input_info
.cbMaxLookahead
);
3551 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %u.\n", input_info
.cbAlignment
);
3553 IMFMediaType_Release(media_type
);
3557 hr
= MFCreateMediaType(&media_type
);
3558 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3560 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3561 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3563 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
3564 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3566 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3567 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3569 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3571 ok(hr
== S_OK
, "Failed to set input type, hr %#x.\n", hr
);
3573 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
3574 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
3576 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3578 ok(hr
== S_OK
, "Failed to set output type, hr %#x.\n", hr
);
3580 memset(&output_info
, 0, sizeof(output_info
));
3581 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
3583 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
3584 ok(output_info
.dwFlags
== 0, "Unexpected flags %#x.\n", output_info
.dwFlags
);
3586 ok(output_info
.cbSize
> 0, "Unexpected size %u.\n", output_info
.cbSize
);
3587 ok(output_info
.cbAlignment
== 0, "Unexpected alignment %u.\n", output_info
.cbAlignment
);
3589 hr
= MFCreateSample(&sample
);
3590 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
3592 hr
= MFCreateSample(&sample2
);
3593 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
3595 memset(&output_buffer
, 0, sizeof(output_buffer
));
3596 output_buffer
.pSample
= sample
;
3598 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3600 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#x.\n", hr
);
3601 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#x.\n", output_buffer
.dwStatus
);
3602 ok(flags
== 0, "Unexpected status %#x.\n", flags
);
3604 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3606 ok(hr
== S_OK
, "Failed to push a sample, hr %#x.\n", hr
);
3608 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3610 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#x.\n", hr
);
3612 memset(&output_buffer
, 0, sizeof(output_buffer
));
3613 output_buffer
.pSample
= sample
;
3615 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3617 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#x.\n", hr
);
3618 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#x.\n", output_buffer
.dwStatus
);
3619 ok(flags
== 0, "Unexpected status %#x.\n", flags
);
3621 hr
= IMFSample_SetSampleTime(sample2
, 0);
3622 ok(hr
== S_OK
, "Failed to set sample time, hr %#x.\n", hr
);
3623 memset(&output_buffer
, 0, sizeof(output_buffer
));
3624 output_buffer
.pSample
= sample
;
3626 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3628 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
3629 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#x.\n", output_buffer
.dwStatus
);
3630 ok(flags
== 0, "Unexpected status %#x.\n", flags
);
3632 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
3633 ok(hr
== S_OK
, "Failed to create a buffer, hr %#x.\n", hr
);
3635 hr
= IMFSample_AddBuffer(sample2
, buffer
);
3636 ok(hr
== S_OK
, "Failed to add a buffer, hr %#x.\n", hr
);
3638 hr
= IMFSample_AddBuffer(sample
, buffer
);
3639 ok(hr
== S_OK
, "Failed to add a buffer, hr %#x.\n", hr
);
3641 memset(&output_buffer
, 0, sizeof(output_buffer
));
3642 output_buffer
.pSample
= sample
;
3644 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3646 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#x.\n", hr
);
3647 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#x.\n", output_buffer
.dwStatus
);
3648 ok(flags
== 0, "Unexpected status %#x.\n", flags
);
3652 memset(&output_buffer
, 0, sizeof(output_buffer
));
3653 output_buffer
.pSample
= sample
;
3655 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3656 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#x.\n", hr
);
3657 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#x.\n", output_buffer
.dwStatus
);
3658 ok(flags
== 0, "Unexpected status %#x.\n", flags
);
3661 IMFSample_Release(sample2
);
3662 IMFSample_Release(sample
);
3663 IMFMediaBuffer_Release(buffer
);
3665 IMFMediaType_Release(media_type
);
3667 IMFTransform_Release(transform
);
3673 static void test_quality_manager(void)
3675 IMFPresentationClock
*clock
;
3676 IMFQualityManager
*manager
;
3677 IMFTopology
*topology
;
3680 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3681 ok(hr
== S_OK
, "Startup failure, hr %#x.\n", hr
);
3683 hr
= MFCreatePresentationClock(&clock
);
3684 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#x.\n", hr
);
3686 hr
= MFCreateStandardQualityManager(&manager
);
3687 ok(hr
== S_OK
, "Failed to create quality manager, hr %#x.\n", hr
);
3689 check_interface(manager
, &IID_IMFQualityManager
, TRUE
);
3690 check_interface(manager
, &IID_IMFClockStateSink
, TRUE
);
3692 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3693 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3695 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3696 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3698 /* Set clock, then shutdown. */
3699 EXPECT_REF(clock
, 1);
3700 EXPECT_REF(manager
, 1);
3701 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3702 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3703 EXPECT_REF(clock
, 2);
3704 EXPECT_REF(manager
, 2);
3706 hr
= IMFQualityManager_Shutdown(manager
);
3707 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3708 EXPECT_REF(clock
, 1);
3710 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3711 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3713 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3714 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3716 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3717 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3719 hr
= IMFQualityManager_Shutdown(manager
);
3720 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3722 IMFQualityManager_Release(manager
);
3724 /* Set clock, then release without shutting down. */
3725 hr
= MFCreateStandardQualityManager(&manager
);
3726 ok(hr
== S_OK
, "Failed to create quality manager, hr %#x.\n", hr
);
3728 EXPECT_REF(clock
, 1);
3729 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3730 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3731 EXPECT_REF(clock
, 2);
3733 IMFQualityManager_Release(manager
);
3734 EXPECT_REF(clock
, 2);
3736 IMFPresentationClock_Release(clock
);
3739 hr
= MFCreateStandardQualityManager(&manager
);
3740 ok(hr
== S_OK
, "Failed to create quality manager, hr %#x.\n", hr
);
3742 hr
= MFCreateTopology(&topology
);
3743 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3745 EXPECT_REF(topology
, 1);
3746 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3747 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3748 EXPECT_REF(topology
, 2);
3750 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3751 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3752 EXPECT_REF(topology
, 1);
3754 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3755 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3757 EXPECT_REF(topology
, 2);
3758 hr
= IMFQualityManager_Shutdown(manager
);
3759 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3760 EXPECT_REF(topology
, 1);
3762 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3763 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
3765 IMFQualityManager_Release(manager
);
3767 hr
= MFCreateStandardQualityManager(&manager
);
3768 ok(hr
== S_OK
, "Failed to create quality manager, hr %#x.\n", hr
);
3770 EXPECT_REF(topology
, 1);
3771 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3772 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3773 EXPECT_REF(topology
, 2);
3775 IMFQualityManager_Release(manager
);
3776 EXPECT_REF(topology
, 1);
3778 IMFTopology_Release(topology
);
3781 ok(hr
== S_OK
, "Shutdown failure, hr %#x.\n", hr
);
3784 static void test_sar(void)
3786 IMFPresentationClock
*present_clock
, *present_clock2
;
3787 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
3788 IMFClockStateSink
*state_sink
, *state_sink2
;
3789 IMFMediaTypeHandler
*handler
, *handler2
;
3790 IMFPresentationTimeSource
*time_source
;
3791 IMFSimpleAudioVolume
*simple_volume
;
3792 IMFAudioStreamVolume
*stream_volume
;
3793 IMFMediaSink
*sink
, *sink2
;
3794 IMFStreamSink
*stream_sink
;
3795 IMFAttributes
*attributes
;
3796 DWORD i
, id
, flags
, count
;
3797 IMFActivate
*activate
;
3798 MFCLOCK_STATE state
;
3806 hr
= CoInitialize(NULL
);
3807 ok(hr
== S_OK
, "Failed to initialize, hr %#x.\n", hr
);
3809 hr
= MFCreateAudioRenderer(NULL
, &sink
);
3810 if (hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
)
3812 skip("No audio playback device available.\n");
3816 ok(hr
== S_OK
, "Failed to create renderer, hr %#x.\n", hr
);
3818 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3819 ok(hr
== S_OK
, "Startup failure, hr %#x.\n", hr
);
3821 hr
= MFCreatePresentationClock(&present_clock
);
3822 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#x.\n", hr
);
3824 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&time_source
);
3826 ok(hr
== S_OK
, "Failed to get time source interface, hr %#x.\n", hr
);
3830 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink2
);
3831 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3832 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
3833 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3834 ok(state_sink
== state_sink2
, "Unexpected clock sink.\n");
3835 IMFClockStateSink_Release(state_sink2
);
3836 IMFClockStateSink_Release(state_sink
);
3838 hr
= IMFPresentationTimeSource_GetUnderlyingClock(time_source
, &clock
);
3839 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#x.\n", hr
);
3841 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &flags
);
3842 ok(hr
== S_OK
, "Failed to get flags, hr %#x.\n", hr
);
3843 ok(flags
== MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
, "Unexpected flags %#x.\n", flags
);
3845 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
3846 ok(hr
== S_OK
, "Failed to get clock state, hr %#x.\n", hr
);
3847 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
3849 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
3850 ok(hr
== S_OK
, "Failed to get state sink, hr %#x.\n", hr
);
3852 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
3853 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
3855 IMFClockStateSink_Release(state_sink
);
3857 IMFPresentationTimeSource_Release(time_source
);
3859 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
3860 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#x.\n", hr
);
3862 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
3863 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#x.\n", hr
);
3865 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
3866 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3868 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3869 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3870 ok(count
== 1, "Unexpected count %u.\n", count
);
3872 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3873 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3874 ok(flags
== (MEDIASINK_FIXED_STREAMS
| MEDIASINK_CAN_PREROLL
), "Unexpected flags %#x.\n", flags
);
3876 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
3877 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
3878 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
3879 check_interface(sink
, &IID_IMFGetService
, TRUE
);
3880 todo_wine
check_interface(sink
, &IID_IMFPresentationTimeSource
, TRUE
);
3881 todo_wine
check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
3882 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, FALSE
);
3883 check_service_interface(sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, TRUE
);
3884 check_service_interface(sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, TRUE
);
3887 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
3888 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
3890 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
3891 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
3893 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
3894 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#x.\n", hr
);
3896 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
3897 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
3899 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
3900 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
3902 IMFClockStateSink_Release(state_sink
);
3904 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
3905 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3907 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
3909 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#x.\n", hr
);
3911 hr
= MFCreateSystemTimeSource(&time_source
);
3912 ok(hr
== S_OK
, "Failed to create time source, hr %#x.\n", hr
);
3914 hr
= IMFPresentationClock_SetTimeSource(present_clock
, time_source
);
3915 ok(hr
== S_OK
, "Failed to set time source, hr %#x.\n", hr
);
3916 IMFPresentationTimeSource_Release(time_source
);
3918 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
3919 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3921 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
3922 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
3924 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
3925 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3926 ok(present_clock
== present_clock2
, "Unexpected instance.\n");
3927 IMFPresentationClock_Release(present_clock2
);
3930 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
3931 ok(hr
== S_OK
, "Failed to get a stream, hr %#x.\n", hr
);
3933 check_interface(stream_sink
, &IID_IMFMediaEventGenerator
, TRUE
);
3934 check_interface(stream_sink
, &IID_IMFMediaTypeHandler
, TRUE
);
3935 todo_wine
check_interface(stream_sink
, &IID_IMFGetService
, TRUE
);
3937 hr
= IMFStreamSink_GetIdentifier(stream_sink
, &id
);
3938 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3939 ok(!id
, "Unexpected id.\n");
3941 hr
= IMFStreamSink_GetMediaSink(stream_sink
, &sink2
);
3942 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3943 ok(sink
== sink2
, "Unexpected object.\n");
3944 IMFMediaSink_Release(sink2
);
3946 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
3947 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3949 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
3950 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3951 ok(handler2
== handler
, "Unexpected instance.\n");
3952 IMFMediaTypeHandler_Release(handler2
);
3954 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3955 ok(hr
== S_OK
, "Failed to get major type, hr %#x.\n", hr
);
3956 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
3959 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3960 ok(hr
== S_OK
, "Failed to get type count, hr %#x.\n", hr
);
3961 ok(!!count
, "Unexpected type count %u.\n", count
);
3963 /* A number of same major/subtype entries are returned, with different degrees of finer format
3964 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
3966 for (i
= 0, found
= -1; i
< count
; ++i
)
3968 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, i
, &mediatype
);
3969 ok(hr
== S_OK
, "Failed to get media type, hr %#x.\n", hr
);
3971 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
)))
3973 IMFMediaType_Release(mediatype
);
3975 if (found
!= -1) break;
3977 ok(found
!= -1, "Haven't found a supported type.\n");
3979 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
3980 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
3982 hr
= MFCreateMediaType(&mediatype
);
3983 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
3985 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
3986 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
3987 ok(FAILED(hr
), "Unexpected hr %#x.\n", hr
);
3989 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3990 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3991 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
3992 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3994 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3995 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
3996 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
3997 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
3999 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
4000 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
4002 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype2
);
4003 ok(hr
== S_OK
, "Failed to get media type, hr %#x.\n", hr
);
4005 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype3
);
4006 ok(hr
== S_OK
, "Failed to get media type, hr %#x.\n", hr
);
4007 ok(mediatype2
== mediatype3
, "Unexpected instance.\n");
4008 IMFMediaType_Release(mediatype3
);
4010 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype2
, NULL
);
4011 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4013 IMFMediaType_Release(mediatype
);
4015 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype2
);
4016 ok(hr
== S_OK
, "Failed to set current type, hr %#x.\n", hr
);
4018 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4019 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4020 ok(mediatype
== mediatype2
, "Unexpected instance.\n");
4021 IMFMediaType_Release(mediatype
);
4023 IMFMediaType_Release(mediatype2
);
4025 /* Reset back to uninitialized state. */
4026 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
4027 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4029 IMFMediaTypeHandler_Release(handler
);
4031 /* State change with initialized stream. */
4032 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4033 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
4035 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4036 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4038 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4039 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4041 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4042 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4044 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4045 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4047 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4048 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4050 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4051 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#x.\n", hr
);
4053 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4054 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4056 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4057 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4059 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4060 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4062 IMFClockStateSink_Release(state_sink
);
4064 IMFStreamSink_Release(stream_sink
);
4066 /* Volume control */
4067 hr
= MFGetService((IUnknown
*)sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, (void **)&simple_volume
);
4068 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
4070 hr
= IMFSimpleAudioVolume_GetMute(simple_volume
, &mute
);
4071 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4073 IMFSimpleAudioVolume_Release(simple_volume
);
4075 hr
= MFGetService((IUnknown
*)sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, (void **)&stream_volume
);
4076 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
4078 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, &count
);
4079 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4081 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, NULL
);
4082 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4084 IMFAudioStreamVolume_Release(stream_volume
);
4086 hr
= MFGetService((IUnknown
*)sink
, &MR_AUDIO_POLICY_SERVICE
, &IID_IMFAudioPolicy
, (void **)&unk
);
4087 ok(hr
== S_OK
, "Failed to get interface, hr %#x.\n", hr
);
4088 IUnknown_Release(unk
);
4091 EXPECT_REF(present_clock
, 2);
4092 hr
= IMFMediaSink_Shutdown(sink
);
4093 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
4094 EXPECT_REF(present_clock
, 1);
4096 hr
= IMFMediaSink_Shutdown(sink
);
4097 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4099 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4100 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4102 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4103 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4105 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4106 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4108 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4109 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4111 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4112 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4114 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4115 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4117 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4118 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4120 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4121 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4123 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4124 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4126 IMFMediaSink_Release(sink
);
4129 hr
= MFCreateAudioRendererActivate(&activate
);
4130 ok(hr
== S_OK
, "Failed to create activation object, hr %#x.\n", hr
);
4132 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4133 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4135 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4136 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4137 ok(sink
== sink2
, "Unexpected instance.\n");
4138 IMFMediaSink_Release(sink2
);
4140 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4141 ok(hr
== S_OK
, "Failed to get sink flags, hr %#x.\n", hr
);
4143 hr
= IMFActivate_ShutdownObject(activate
);
4144 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
4146 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4147 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4149 IMFMediaSink_Release(sink
);
4151 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4152 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4154 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4156 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4158 IMFMediaSink_Release(sink
);
4160 hr
= IMFActivate_DetachObject(activate
);
4161 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4163 IMFActivate_Release(activate
);
4165 IMFPresentationClock_Release(present_clock
);
4168 ok(hr
== S_OK
, "Shutdown failure, hr %#x.\n", hr
);
4170 /* SAR attributes */
4171 hr
= MFCreateAttributes(&attributes
, 0);
4172 ok(hr
== S_OK
, "Failed to create attributes, hr %#x.\n", hr
);
4175 hr
= IMFAttributes_SetUINT32(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
, eMultimedia
);
4176 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4178 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4179 ok(hr
== S_OK
, "Failed to create a sink, hr %#x.\n", hr
);
4180 IMFMediaSink_Release(sink
);
4182 /* Invalid endpoint. */
4183 hr
= IMFAttributes_SetString(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
, L
"endpoint");
4184 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4186 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4187 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
4189 hr
= IMFAttributes_DeleteItem(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
);
4190 ok(hr
== S_OK
, "Failed to remove attribute, hr %#x.\n", hr
);
4192 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4193 ok(hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
, "Failed to create a sink, hr %#x.\n", hr
);
4198 static void test_evr(void)
4200 IMFVideoSampleAllocatorCallback
*allocator_callback
;
4201 IMFStreamSink
*stream_sink
, *stream_sink2
;
4202 IMFVideoDisplayControl
*display_control
;
4203 IMFMediaType
*media_type
, *media_type2
;
4204 IMFVideoSampleAllocator
*allocator
;
4205 IMFMediaTypeHandler
*type_handler
;
4206 IMFVideoRenderer
*video_renderer
;
4207 IMFMediaSink
*sink
, *sink2
;
4208 IMFAttributes
*attributes
;
4209 DWORD flags
, count
, value
;
4210 IMFActivate
*activate
;
4211 HWND window
, window2
;
4220 hr
= CoInitialize(NULL
);
4221 ok(hr
== S_OK
, "Failed to initialize, hr %#x.\n", hr
);
4223 hr
= MFCreateVideoRenderer(&IID_IMFVideoRenderer
, (void **)&video_renderer
);
4224 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4226 hr
= IMFVideoRenderer_InitializeRenderer(video_renderer
, NULL
, NULL
);
4227 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4229 IMFVideoRenderer_Release(video_renderer
);
4231 hr
= MFCreateVideoRendererActivate(NULL
, NULL
);
4232 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4235 window
= create_window();
4236 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4237 ok(hr
== S_OK
, "Failed to create activate object, hr %#x.\n", hr
);
4239 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4240 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
4241 ok(UlongToHandle(window3
) == window
, "Unexpected value.\n");
4243 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4244 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4246 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4247 check_interface(sink
, &IID_IMFVideoRenderer
, TRUE
);
4248 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4249 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4250 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4251 check_interface(sink
, &IID_IMFQualityAdvise
, TRUE
);
4253 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
,
4254 (void **)&display_control
);
4255 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4258 hr
= IMFVideoDisplayControl_GetVideoWindow(display_control
, &window2
);
4259 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4260 ok(window2
== window
, "Unexpected window %p.\n", window2
);
4262 IMFVideoDisplayControl_Release(display_control
);
4263 IMFMediaSink_Release(sink
);
4264 IMFActivate_Release(activate
);
4265 DestroyWindow(window
);
4267 hr
= MFCreateVideoRendererActivate(NULL
, &activate
);
4268 ok(hr
== S_OK
, "Failed to create activate object, hr %#x.\n", hr
);
4270 hr
= IMFActivate_GetCount(activate
, &count
);
4271 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
4272 ok(count
== 1, "Unexpected count %u.\n", count
);
4274 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4275 ok(hr
== S_OK
, "Failed to get attribute, hr %#x.\n", hr
);
4276 ok(!window3
, "Unexpected value.\n");
4278 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4279 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4281 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFAttributes
, (void **)&attributes
);
4282 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4283 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFMediaSink
, (void **)&unk
);
4284 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4285 IUnknown_Release(unk
);
4286 hr
= IMFAttributes_GetCount(attributes
, &count
);
4287 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4288 ok(!!count
, "Unexpected count %u.\n", count
);
4289 /* Rendering preferences are not immediately propagated to the presenter. */
4290 hr
= IMFAttributes_SetUINT32(attributes
, &EVRConfig_ForceBob
, 1);
4291 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4292 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, (void **)&display_control
);
4293 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4294 hr
= IMFVideoDisplayControl_GetRenderingPrefs(display_control
, &flags
);
4295 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4296 ok(!flags
, "Unexpected flags %#x.\n", flags
);
4297 IMFVideoDisplayControl_Release(display_control
);
4298 IMFAttributes_Release(attributes
);
4300 /* Primary stream type handler. */
4301 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4302 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4304 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFAttributes
, (void **)&attributes
);
4305 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4306 hr
= IMFAttributes_GetCount(attributes
, &count
);
4307 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4308 ok(count
== 2, "Unexpected count %u.\n", count
);
4310 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, &value
);
4311 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4312 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4314 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D_AWARE
, &value
);
4315 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4316 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4318 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFStreamSink
, (void **)&unk
);
4319 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4320 IUnknown_Release(unk
);
4321 IMFAttributes_Release(attributes
);
4323 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
4324 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4326 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, NULL
);
4327 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4329 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, &guid
);
4330 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4331 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4333 /* Supported types are not advertised. */
4334 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, NULL
);
4335 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4338 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, &count
);
4339 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4340 ok(!count
, "Unexpected count %u.\n", count
);
4342 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, NULL
);
4343 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
4345 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, &media_type
);
4346 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
4348 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, NULL
);
4349 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4351 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type
);
4352 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4354 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, NULL
);
4355 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4357 hr
= MFCreateMediaType(&media_type
);
4358 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4360 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4361 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4363 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4364 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4366 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
4367 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4369 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, NULL
, NULL
);
4370 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4372 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4373 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#x.\n", hr
);
4375 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
4376 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4378 media_type2
= (void *)0x1;
4379 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4380 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4381 ok(!media_type2
, "Unexpected media type %p.\n", media_type2
);
4383 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
4384 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4386 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type2
);
4387 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4388 hr
= IMFMediaType_QueryInterface(media_type2
, &IID_IMFVideoMediaType
, (void **)&unk
);
4389 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4390 IUnknown_Release(unk
);
4391 IMFMediaType_Release(media_type2
);
4393 IMFMediaType_Release(media_type
);
4395 IMFMediaTypeHandler_Release(type_handler
);
4397 /* Stream uses an allocator. */
4398 hr
= MFGetService((IUnknown
*)stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4399 (void **)&allocator
);
4400 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4402 hr
= IMFVideoSampleAllocator_QueryInterface(allocator
, &IID_IMFVideoSampleAllocatorCallback
, (void **)&allocator_callback
);
4403 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4406 hr
= IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback
, &sample_count
);
4407 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4408 ok(!sample_count
, "Unexpected sample count %d.\n", sample_count
);
4410 hr
= IMFVideoSampleAllocator_AllocateSample(allocator
, &sample
);
4411 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
4413 IMFVideoSampleAllocatorCallback_Release(allocator_callback
);
4414 IMFVideoSampleAllocator_Release(allocator
);
4416 /* Same test for a substream. */
4417 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream_sink2
);
4418 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4420 hr
= MFGetService((IUnknown
*)stream_sink2
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4421 (void **)&allocator
);
4422 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4423 IMFVideoSampleAllocator_Release(allocator
);
4425 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
4426 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4428 IMFStreamSink_Release(stream_sink2
);
4430 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4431 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4432 ok(flags
== (MEDIASINK_CAN_PREROLL
| MEDIASINK_CLOCK_REQUIRED
), "Unexpected flags %#x.\n", flags
);
4434 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFGetService
, (void **)&gs
);
4435 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4437 hr
= IMFGetService_GetService(gs
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, (void **)&unk
);
4438 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4439 IUnknown_Release(unk
);
4441 IMFGetService_Release(gs
);
4443 hr
= IMFActivate_ShutdownObject(activate
);
4444 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
4446 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4447 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4449 /* Activate again. */
4450 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4451 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4453 ok(sink
== sink2
, "Unexpected instance.\n");
4454 IMFMediaSink_Release(sink2
);
4456 hr
= IMFActivate_DetachObject(activate
);
4457 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4459 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4460 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#x.\n", hr
);
4462 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4463 ok(hr
== S_OK
, "Failed to activate, hr %#x.\n", hr
);
4465 hr
= IMFActivate_ShutdownObject(activate
);
4466 ok(hr
== S_OK
, "Failed to shut down, hr %#x.\n", hr
);
4468 IMFMediaSink_Release(sink2
);
4469 IMFMediaSink_Release(sink
);
4471 IMFActivate_Release(activate
);
4476 static void test_MFCreateSimpleTypeHandler(void)
4478 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
4479 IMFMediaTypeHandler
*handler
;
4484 hr
= MFCreateSimpleTypeHandler(&handler
);
4485 ok(hr
== S_OK
, "Failed to create object, hr %#x.\n", hr
);
4487 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
4488 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4490 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
4491 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#x.\n", hr
);
4494 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
4495 ok(hr
== S_OK
, "Failed to get type count, hr %#x.\n", hr
);
4496 ok(count
== 1, "Unexpected count %u.\n", count
);
4498 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
4499 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4501 media_type
= (void *)0xdeadbeef;
4502 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
4503 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4504 ok(!media_type
, "Unexpected pointer.\n");
4506 hr
= MFCreateMediaType(&media_type
);
4507 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
4509 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
4510 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#x.\n", hr
);
4512 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
4513 ok(hr
== S_OK
, "Failed to set current type, hr %#x.\n", hr
);
4515 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type2
);
4516 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4517 ok(media_type2
== media_type
, "Unexpected type.\n");
4518 IMFMediaType_Release(media_type2
);
4520 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
4521 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
4523 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
4524 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
4526 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type2
);
4527 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
4529 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 1, &media_type2
);
4530 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
4532 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
4533 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4534 ok(media_type
== media_type2
, "Unexpected pointer.\n");
4535 IMFMediaType_Release(media_type2
);
4537 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4538 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#x.\n", hr
);
4540 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4541 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4543 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4544 ok(hr
== S_OK
, "Failed to get major type, hr %#x.\n", hr
);
4545 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
4547 hr
= MFCreateMediaType(&media_type3
);
4548 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
4550 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, NULL
);
4551 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
4553 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
4554 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4556 /* Different major types. */
4557 media_type2
= (void *)0xdeadbeef;
4558 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4559 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
4560 ok(!media_type2
, "Unexpected pointer.\n");
4562 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4563 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4565 media_type2
= (void *)0xdeadbeef;
4566 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4567 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4568 ok(!media_type2
, "Unexpected pointer.\n");
4570 /* Handler missing subtype. */
4571 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
4572 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4574 media_type2
= (void *)0xdeadbeef;
4575 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4576 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
4577 ok(!media_type2
, "Unexpected pointer.\n");
4579 /* Different subtypes. */
4580 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
4581 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4583 media_type2
= (void *)0xdeadbeef;
4584 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4585 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
4586 ok(!media_type2
, "Unexpected pointer.\n");
4588 /* Same major/subtype. */
4589 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
4590 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4592 media_type2
= (void *)0xdeadbeef;
4593 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4594 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4595 ok(!media_type2
, "Unexpected pointer.\n");
4597 /* Set one more attribute. */
4598 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)4 << 32 | 4);
4599 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4601 media_type2
= (void *)0xdeadbeef;
4602 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4603 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4604 ok(!media_type2
, "Unexpected pointer.\n");
4606 IMFMediaType_Release(media_type3
);
4607 IMFMediaType_Release(media_type
);
4609 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
4610 ok(hr
== S_OK
, "Failed to set current type, hr %#x.\n", hr
);
4612 media_type
= (void *)0xdeadbeef;
4613 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
4614 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4615 ok(!media_type
, "Unexpected pointer.\n");
4617 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4618 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#x.\n", hr
);
4620 IMFMediaTypeHandler_Release(handler
);
4623 static void test_MFGetSupportedMimeTypes(void)
4628 hr
= MFGetSupportedMimeTypes(NULL
);
4629 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4631 value
.vt
= VT_EMPTY
;
4632 hr
= MFGetSupportedMimeTypes(&value
);
4633 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4634 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
4636 PropVariantClear(&value
);
4639 static void test_MFGetSupportedSchemes(void)
4644 hr
= MFGetSupportedSchemes(NULL
);
4645 ok(hr
== E_POINTER
, "Unexpected hr %#x.\n", hr
);
4647 value
.vt
= VT_EMPTY
;
4648 hr
= MFGetSupportedSchemes(&value
);
4649 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4650 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
4652 PropVariantClear(&value
);
4655 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
4661 hr
= IMFMediaType_GetMajorType(type
, &major
);
4662 ok(hr
== S_OK
, "Failed to get major type, hr %#x.\n", hr
);
4664 hr
= IMFMediaType_GetCount(type
, &count
);
4665 ok(hr
== S_OK
, "Failed to get attribute count, hr %#x.\n", hr
);
4666 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
4668 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
4671 static void test_sample_copier(void)
4673 IMFAttributes
*attributes
, *attributes2
;
4674 DWORD in_min
, in_max
, out_min
, out_max
;
4675 IMFMediaType
*mediatype
, *mediatype2
;
4676 MFT_OUTPUT_STREAM_INFO output_info
;
4677 IMFSample
*sample
, *client_sample
;
4678 MFT_INPUT_STREAM_INFO input_info
;
4679 DWORD input_count
, output_count
;
4680 MFT_OUTPUT_DATA_BUFFER buffer
;
4681 IMFMediaBuffer
*media_buffer
;
4682 DWORD count
, flags
, status
;
4683 IMFTransform
*copier
;
4687 if (!pMFCreateSampleCopierMFT
)
4689 win_skip("MFCreateSampleCopierMFT() is not available.\n");
4693 hr
= pMFCreateSampleCopierMFT(&copier
);
4694 ok(hr
== S_OK
, "Failed to create sample copier, hr %#x.\n", hr
);
4696 hr
= IMFTransform_GetAttributes(copier
, &attributes
);
4697 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#x.\n", hr
);
4698 hr
= IMFTransform_GetAttributes(copier
, &attributes2
);
4699 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#x.\n", hr
);
4700 ok(attributes
== attributes2
, "Unexpected instance.\n");
4701 IMFAttributes_Release(attributes2
);
4702 hr
= IMFAttributes_GetCount(attributes
, &count
);
4703 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4704 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
4705 hr
= IMFAttributes_GetUINT32(attributes
, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, &value
);
4706 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4707 ok(!!value
, "Unexpected value %u.\n", value
);
4708 IMFAttributes_Release(attributes
);
4710 hr
= IMFTransform_GetInputStreamAttributes(copier
, 0, &attributes
);
4711 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4713 hr
= IMFTransform_GetInputStreamAttributes(copier
, 1, &attributes
);
4714 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4716 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 0, &attributes
);
4717 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4719 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 1, &attributes
);
4720 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4722 hr
= IMFTransform_SetOutputBounds(copier
, 0, 0);
4723 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4725 /* No dynamic streams. */
4726 input_count
= output_count
= 0;
4727 hr
= IMFTransform_GetStreamCount(copier
, &input_count
, &output_count
);
4728 ok(hr
== S_OK
, "Failed to get stream count, hr %#x.\n", hr
);
4729 ok(input_count
== 1 && output_count
== 1, "Unexpected streams count.\n");
4731 hr
= IMFTransform_GetStreamLimits(copier
, &in_min
, &in_max
, &out_min
, &out_max
);
4732 ok(hr
== S_OK
, "Failed to get stream limits, hr %#x.\n", hr
);
4733 ok(in_min
== in_max
&& in_min
== 1 && out_min
== out_max
&& out_min
== 1, "Unexpected stream limits.\n");
4735 hr
= IMFTransform_GetStreamIDs(copier
, 1, &input_count
, 1, &output_count
);
4736 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4738 hr
= IMFTransform_DeleteInputStream(copier
, 0);
4739 ok(hr
== E_NOTIMPL
, "Unexpected hr %#x.\n", hr
);
4741 /* Available types. */
4742 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
4743 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4744 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
4745 IMFMediaType_Release(mediatype
);
4747 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
4748 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4749 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
4750 IMFMediaType_Release(mediatype
);
4752 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
4753 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
4755 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
4756 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
4758 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
4759 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#x.\n", hr
);
4761 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
4762 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
4764 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype
);
4765 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4767 hr
= IMFTransform_GetInputCurrentType(copier
, 1, &mediatype
);
4768 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
4770 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype
);
4771 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4773 hr
= IMFTransform_GetOutputCurrentType(copier
, 1, &mediatype
);
4774 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#x.\n", hr
);
4776 hr
= MFCreateSample(&sample
);
4777 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
4779 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
4780 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4782 hr
= MFCreateMediaType(&mediatype
);
4783 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
4785 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
4786 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#x.\n", hr
);
4788 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4789 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4791 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
4792 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4794 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
4795 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
4797 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
4798 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
4799 ok(!output_info
.dwFlags
, "Unexpected flags %#x.\n", output_info
.dwFlags
);
4800 ok(!output_info
.cbSize
, "Unexpected size %u.\n", output_info
.cbSize
);
4801 ok(!output_info
.cbAlignment
, "Unexpected alignment %u.\n", output_info
.cbAlignment
);
4803 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
4804 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
4806 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
4807 ok(!input_info
.dwFlags
, "Unexpected flags %#x.\n", input_info
.dwFlags
);
4808 ok(!input_info
.cbSize
, "Unexpected size %u.\n", input_info
.cbSize
);
4809 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %u.\n", input_info
.cbMaxLookahead
);
4810 ok(!input_info
.cbAlignment
, "Unexpected alignment %u.\n", input_info
.cbAlignment
);
4812 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
4813 ok(hr
== S_OK
, "Failed to set input type, hr %#x.\n", hr
);
4815 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
4816 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
4817 ok(!output_info
.dwFlags
, "Unexpected flags %#x.\n", output_info
.dwFlags
);
4818 ok(output_info
.cbSize
== 16 * 16, "Unexpected size %u.\n", output_info
.cbSize
);
4819 ok(!output_info
.cbAlignment
, "Unexpected alignment %u.\n", output_info
.cbAlignment
);
4821 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
4822 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
4823 IMFMediaType_Release(mediatype2
);
4825 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
4826 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4828 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
4829 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4831 /* Setting input type resets output type. */
4832 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
4833 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4834 IMFMediaType_Release(mediatype2
);
4836 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
4837 ok(hr
== S_OK
, "Failed to set input type, hr %#x.\n", hr
);
4839 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
4840 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4842 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
4843 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4844 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
4845 IMFMediaType_Release(mediatype2
);
4847 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
4848 ok(hr
== S_OK
, "Failed to get stream info, hr %#x.\n", hr
);
4849 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
4850 ok(!input_info
.dwFlags
, "Unexpected flags %#x.\n", input_info
.dwFlags
);
4851 ok(input_info
.cbSize
== 16 * 16, "Unexpected size %u.\n", input_info
.cbSize
);
4852 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %u.\n", input_info
.cbMaxLookahead
);
4853 ok(!input_info
.cbAlignment
, "Unexpected alignment %u.\n", input_info
.cbAlignment
);
4855 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
4856 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4857 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
4858 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4859 IMFMediaType_Release(mediatype2
);
4861 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
4862 ok(hr
== S_OK
, "Failed to get input status, hr %#x.\n", hr
);
4863 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#x.\n", flags
);
4865 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
4866 ok(hr
== S_OK
, "Failed to get current type, hr %#x.\n", hr
);
4867 IMFMediaType_Release(mediatype2
);
4869 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
4870 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#x.\n", hr
);
4872 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
4873 ok(hr
== S_OK
, "Failed to set output type, hr %#x.\n", hr
);
4875 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
4876 ok(hr
== S_OK
, "Failed to get output status, hr %#x.\n", hr
);
4877 ok(!flags
, "Unexpected flags %#x.\n", flags
);
4879 /* Pushing samples. */
4880 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
4881 ok(hr
== S_OK
, "Failed to create media buffer, hr %#x.\n", hr
);
4883 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
4884 ok(hr
== S_OK
, "Failed to add a buffer, hr %#x.\n", hr
);
4885 IMFMediaBuffer_Release(media_buffer
);
4887 EXPECT_REF(sample
, 1);
4888 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
4889 ok(hr
== S_OK
, "Failed to process input, hr %#x.\n", hr
);
4890 EXPECT_REF(sample
, 2);
4892 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
4893 ok(hr
== S_OK
, "Failed to get input status, hr %#x.\n", hr
);
4894 ok(!flags
, "Unexpected flags %#x.\n", flags
);
4896 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
4897 ok(hr
== S_OK
, "Failed to get output status, hr %#x.\n", hr
);
4898 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#x.\n", flags
);
4900 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
4901 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#x.\n", hr
);
4903 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
4904 ok(hr
== S_OK
, "Failed to get output info, hr %#x.\n", hr
);
4906 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
4907 ok(hr
== S_OK
, "Failed to create media buffer, hr %#x.\n", hr
);
4909 hr
= MFCreateSample(&client_sample
);
4910 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
4912 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
4913 ok(hr
== S_OK
, "Failed to add a buffer, hr %#x.\n", hr
);
4914 IMFMediaBuffer_Release(media_buffer
);
4917 memset(&buffer
, 0, sizeof(buffer
));
4918 buffer
.pSample
= client_sample
;
4919 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
4920 ok(hr
== S_OK
, "Failed to get output, hr %#x.\n", hr
);
4921 EXPECT_REF(sample
, 1);
4923 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
4924 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#x.\n", hr
);
4927 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
4928 ok(hr
== S_OK
, "Failed to process input, hr %#x.\n", hr
);
4929 EXPECT_REF(sample
, 2);
4931 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
4932 ok(hr
== S_OK
, "Failed to flush, hr %#x.\n", hr
);
4933 EXPECT_REF(sample
, 1);
4935 IMFSample_Release(sample
);
4936 IMFSample_Release(client_sample
);
4938 IMFMediaType_Release(mediatype
);
4939 IMFTransform_Release(copier
);
4942 struct sample_metadata
4949 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
4950 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
4952 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
4953 IMFSample
*input_sample
, *output_sample
;
4954 MFT_OUTPUT_DATA_BUFFER buffer
;
4960 hr
= MFCreateSample(&input_sample
);
4961 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
4965 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
4966 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4968 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
4969 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4971 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
4972 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4975 hr
= MFCreateSample(&output_sample
);
4976 ok(hr
== S_OK
, "Failed to create a sample, hr %#x.\n", hr
);
4978 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
4979 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4981 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
4982 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4984 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
4985 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4987 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
4988 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4990 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
4991 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
4993 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
4994 ok(hr
== S_OK
, "Failed to process input, hr %#x.\n", hr
);
4997 memset(&buffer
, 0, sizeof(buffer
));
4998 buffer
.pSample
= output_sample
;
4999 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5000 ok(hr
== S_OK
, "Failed to get output, hr %#x.\n", hr
);
5002 if (!md
) md
= &zero_md
;
5004 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
5005 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5006 ok(md
->flags
== flags
, "Unexpected flags.\n");
5007 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
5008 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5009 ok(md
->time
== time
, "Unexpected time.\n");
5010 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
5011 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5012 ok(md
->duration
== time
, "Unexpected duration.\n");
5014 IMFSample_Release(input_sample
);
5015 IMFSample_Release(output_sample
);
5018 static void test_sample_copier_output_processing(void)
5020 IMFMediaBuffer
*input_buffer
, *output_buffer
;
5021 MFT_OUTPUT_STREAM_INFO output_info
;
5022 struct sample_metadata md
;
5023 IMFMediaType
*mediatype
;
5024 IMFTransform
*copier
;
5029 if (!pMFCreateSampleCopierMFT
)
5032 hr
= pMFCreateSampleCopierMFT(&copier
);
5033 ok(hr
== S_OK
, "Failed to create sample copier, hr %#x.\n", hr
);
5035 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
5036 hr
= MFCreateMediaType(&mediatype
);
5037 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
5039 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5040 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
5042 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5043 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
5045 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5046 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
5048 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5049 ok(hr
== S_OK
, "Failed to set input type, hr %#x.\n", hr
);
5051 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5052 ok(hr
== S_OK
, "Failed to set input type, hr %#x.\n", hr
);
5054 /* Source and destination are linear buffers, destination is twice as large. */
5055 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5056 ok(hr
== S_OK
, "Failed to get output info, hr %#x.\n", hr
);
5058 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
5059 ok(hr
== S_OK
, "Failed to create media buffer, hr %#x.\n", hr
);
5061 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5062 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5063 memset(ptr
, 0xcc, max_length
);
5064 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5065 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5067 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
5068 ok(hr
== S_OK
, "Failed to create media buffer, hr %#x.\n", hr
);
5070 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
5071 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5072 memset(ptr
, 0xaa, max_length
);
5073 hr
= IMFMediaBuffer_Unlock(input_buffer
);
5074 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5075 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
5076 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5078 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
5080 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5081 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5082 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
5084 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5085 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5090 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
5092 IMFMediaBuffer_Release(input_buffer
);
5093 IMFMediaBuffer_Release(output_buffer
);
5095 IMFMediaType_Release(mediatype
);
5096 IMFTransform_Release(copier
);
5099 static void test_MFGetTopoNodeCurrentType(void)
5101 IMFMediaType
*media_type
, *media_type2
;
5102 IMFTopologyNode
*node
;
5105 if (!pMFGetTopoNodeCurrentType
)
5107 win_skip("MFGetTopoNodeCurrentType() is unsupported.\n");
5112 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
5113 ok(hr
== S_OK
, "Failed to create a node, hr %#x.\n", hr
);
5115 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5116 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
5118 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5119 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
5121 hr
= MFCreateMediaType(&media_type2
);
5122 ok(hr
== S_OK
, "Failed to create media type, hr %#x.\n", hr
);
5124 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5125 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
5127 /* Input type returned, if set. */
5128 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, media_type2
);
5129 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5131 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5132 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5133 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5134 IMFMediaType_Release(media_type
);
5136 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
5137 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5139 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5140 ok(hr
== E_INVALIDARG
, "Unexpected hr %#x.\n", hr
);
5142 /* Set second output. */
5143 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5144 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5146 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5147 ok(hr
== E_FAIL
, "Unexpected hr %#x.\n", hr
);
5149 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, NULL
);
5150 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5152 /* Set first output. */
5153 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, media_type2
);
5154 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5156 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5157 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5158 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5159 IMFMediaType_Release(media_type
);
5161 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, NULL
);
5162 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5164 /* Set primary output. */
5165 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5166 ok(hr
== S_OK
, "Failed to set media type, hr %#x.\n", hr
);
5168 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_PRIMARYOUTPUT
, 1);
5169 ok(hr
== S_OK
, "Failed to set attribute, hr %#x.\n", hr
);
5171 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5172 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5173 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5174 IMFMediaType_Release(media_type
);
5176 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5177 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5178 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5179 IMFMediaType_Release(media_type
);
5181 IMFTopologyNode_Release(node
);
5182 IMFMediaType_Release(media_type2
);
5185 static void init_functions(void)
5187 HMODULE mod
= GetModuleHandleA("mf.dll");
5189 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
5190 X(MFCreateSampleCopierMFT
);
5191 X(MFGetTopoNodeCurrentType
);
5195 static void test_MFRequireProtectedEnvironment(void)
5197 IMFPresentationDescriptor
*pd
;
5198 IMFMediaType
*mediatype
;
5199 IMFStreamDescriptor
*sd
;
5202 hr
= MFCreateMediaType(&mediatype
);
5203 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5205 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
5206 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#x.\n", hr
);
5208 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
5209 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#x.\n", hr
);
5211 hr
= IMFPresentationDescriptor_SelectStream(pd
, 0);
5212 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5214 hr
= MFRequireProtectedEnvironment(pd
);
5215 ok(hr
== S_FALSE
, "Unexpected hr %#x.\n", hr
);
5217 hr
= IMFStreamDescriptor_SetUINT32(sd
, &MF_SD_PROTECTED
, 1);
5218 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5220 hr
= MFRequireProtectedEnvironment(pd
);
5221 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5223 hr
= IMFPresentationDescriptor_DeselectStream(pd
, 0);
5224 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5226 hr
= MFRequireProtectedEnvironment(pd
);
5227 ok(hr
== S_OK
, "Unexpected hr %#x.\n", hr
);
5229 IMFStreamDescriptor_Release(sd
);
5230 IMFPresentationDescriptor_Release(pd
);
5239 win_skip("Skipping tests on Vista.\n");
5244 test_topology_tee_node();
5245 test_topology_loader();
5246 test_topology_loader_evr();
5247 test_MFGetService();
5248 test_sequencer_source();
5249 test_media_session();
5250 test_MFShutdownObject();
5251 test_presentation_clock();
5252 test_sample_grabber();
5253 test_sample_grabber_is_mediatype_supported();
5254 test_video_processor();
5255 test_quality_manager();
5258 test_MFCreateSimpleTypeHandler();
5259 test_MFGetSupportedMimeTypes();
5260 test_MFGetSupportedSchemes();
5261 test_sample_copier();
5262 test_sample_copier_output_processing();
5263 test_MFGetTopoNodeCurrentType();
5264 test_MFRequireProtectedEnvironment();