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 #include "wmcodecdsp.h"
34 #include "propvarutil.h"
36 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
37 DEFINE_GUID(MFVideoFormat_P208
, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
38 DEFINE_GUID(MFVideoFormat_ABGR32
, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
47 #include "mmdeviceapi.h"
48 #include "audioclient.h"
53 #include "wine/test.h"
55 static HRESULT (WINAPI
*pMFCreateSampleCopierMFT
)(IMFTransform
**copier
);
56 static HRESULT (WINAPI
*pMFGetTopoNodeCurrentType
)(IMFTopologyNode
*node
, DWORD stream
, BOOL output
, IMFMediaType
**type
);
58 static BOOL
is_vista(void)
60 return !pMFGetTopoNodeCurrentType
;
63 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
64 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
68 refcount
= IUnknown_Release(obj
);
69 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
73 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
74 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
76 IUnknown
*iface
= iface_ptr
;
77 HRESULT hr
, expected_hr
;
80 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
82 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
83 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
85 IUnknown_Release(unk
);
88 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
89 static void check_service_interface_(unsigned int line
, void *iface_ptr
, REFGUID service
, REFIID iid
, BOOL supported
)
91 IUnknown
*iface
= iface_ptr
;
92 HRESULT hr
, expected_hr
;
95 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
97 hr
= MFGetService(iface
, service
, iid
, (void **)&unk
);
98 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
100 IUnknown_Release(unk
);
103 struct attribute_desc
112 typedef struct attribute_desc media_type_desc
[32];
114 #define ATTR_GUID(k, g, ...) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}, __VA_ARGS__ }
115 #define ATTR_UINT32(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}, __VA_ARGS__ }
116 #define ATTR_BLOB(k, p, n, ...) {.key = &k, .name = #k, {.vt = VT_VECTOR | VT_UI1, .caub = {.pElems = (void *)p, .cElems = n}}, __VA_ARGS__ }
117 #define ATTR_RATIO(k, n, d, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.HighPart = n, .LowPart = d}}, .ratio = TRUE, __VA_ARGS__ }
118 #define ATTR_UINT64(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.QuadPart = v}}, __VA_ARGS__ }
120 #define check_media_type(a, b, c) check_attributes_(__LINE__, (IMFAttributes *)a, b, c)
121 #define check_attributes(a, b, c) check_attributes_(__LINE__, a, b, c)
122 static void check_attributes_(int line
, IMFAttributes
*attributes
, const struct attribute_desc
*desc
, ULONG limit
)
124 char buffer
[256], *buf
= buffer
;
129 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
131 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
132 todo_wine_if(desc
[i
].todo
)
133 ok_(__FILE__
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
134 if (hr
!= S_OK
) continue;
138 default: sprintf(buffer
, "??"); break;
139 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
140 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
143 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
145 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
147 case VT_VECTOR
| VT_UI1
:
148 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
149 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
150 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
151 if (value
.caub
.cElems
> 16)
152 buf
+= sprintf(buf
, "...}");
154 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
158 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
159 todo_wine_if(desc
[i
].todo_value
)
160 ok_(__FILE__
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
161 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
165 static HWND
create_window(void)
167 RECT r
= {0, 0, 640, 480};
169 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
171 return CreateWindowA("static", "mf_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
172 0, 0, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
175 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
177 if (IsEqualIID(riid
, &IID_IUnknown
))
180 IUnknown_AddRef(iface
);
185 return E_NOINTERFACE
;
188 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
193 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
198 static const IUnknownVtbl test_unk_vtbl
=
200 test_unk_QueryInterface
,
205 static void test_topology(void)
207 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
208 IMFCollection
*collection
, *collection2
;
209 IUnknown test_unk2
= { &test_unk_vtbl
};
210 IUnknown test_unk
= { &test_unk_vtbl
};
211 IMFTopologyNode
*node
, *node2
, *node3
;
212 IMFTopology
*topology
, *topology2
;
213 DWORD size
, io_count
, index
;
214 MF_TOPOLOGY_TYPE node_type
;
221 hr
= MFCreateTopology(NULL
);
222 ok(hr
== E_POINTER
, "got %#lx\n", hr
);
224 hr
= MFCreateTopology(&topology
);
225 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
226 hr
= IMFTopology_GetTopologyID(topology
, &id
);
227 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
228 ok(id
== 1, "Unexpected id.\n");
230 hr
= MFCreateTopology(&topology2
);
231 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
232 hr
= IMFTopology_GetTopologyID(topology2
, &id
);
233 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
234 ok(id
== 2, "Unexpected id.\n");
236 IMFTopology_Release(topology
);
238 hr
= MFCreateTopology(&topology
);
239 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
240 hr
= IMFTopology_GetTopologyID(topology
, &id
);
241 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
242 ok(id
== 3, "Unexpected id.\n");
244 IMFTopology_Release(topology2
);
246 /* No attributes by default. */
247 for (node_type
= MF_TOPOLOGY_OUTPUT_NODE
; node_type
< MF_TOPOLOGY_TEE_NODE
; ++node_type
)
249 hr
= MFCreateTopologyNode(node_type
, &node
);
250 ok(hr
== S_OK
, "Failed to create a node for type %d, hr %#lx.\n", node_type
, hr
);
251 hr
= IMFTopologyNode_GetCount(node
, &count
);
252 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
253 ok(!count
, "Unexpected attribute count %u.\n", count
);
254 IMFTopologyNode_Release(node
);
257 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, NULL
);
258 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
260 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
261 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
263 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
264 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
266 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
267 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
268 ok(((id
>> 32) == GetCurrentProcessId()) && !!(id
& 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id
));
270 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
271 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
273 hr
= IMFTopology_GetNodeCount(topology
, NULL
);
274 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
276 hr
= IMFTopology_AddNode(topology
, NULL
);
277 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
280 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
281 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
282 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
284 /* Same id, different nodes. */
285 hr
= IMFTopology_AddNode(topology
, node
);
286 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
289 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
290 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
291 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
293 hr
= IMFTopology_AddNode(topology
, node2
);
294 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
295 IMFTopologyNode_Release(node2
);
297 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
298 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
299 ok(node2
== node
, "Unexpected node.\n");
300 IMFTopologyNode_Release(node2
);
302 /* Change node id, add it again. */
303 hr
= IMFTopologyNode_SetTopoNodeID(node
, ++id
);
304 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
306 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
307 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
308 ok(node2
== node
, "Unexpected node.\n");
309 IMFTopologyNode_Release(node2
);
311 hr
= IMFTopology_GetNodeByID(topology
, id
+ 1, &node2
);
312 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
314 hr
= IMFTopology_AddNode(topology
, node
);
315 ok(hr
== E_INVALIDARG
, "Failed to add a node, hr %#lx.\n", hr
);
317 hr
= IMFTopology_GetNode(topology
, 0, &node2
);
318 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
319 ok(node2
== node
, "Unexpected node.\n");
320 IMFTopologyNode_Release(node2
);
322 hr
= IMFTopology_GetNode(topology
, 1, NULL
);
323 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
325 hr
= IMFTopology_GetNode(topology
, 1, &node2
);
326 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
328 hr
= IMFTopology_GetNode(topology
, -2, &node2
);
329 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
331 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
332 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
333 hr
= IMFTopology_AddNode(topology
, node2
);
334 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
335 IMFTopologyNode_Release(node2
);
338 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
339 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
340 ok(node_count
== 2, "Unexpected node count %u.\n", node_count
);
342 /* Remove with detached node, existing id. */
343 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
344 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
345 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
346 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
347 hr
= IMFTopology_RemoveNode(topology
, node2
);
348 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
349 IMFTopologyNode_Release(node2
);
351 hr
= IMFTopology_RemoveNode(topology
, node
);
352 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
355 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
356 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
357 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
359 hr
= IMFTopology_Clear(topology
);
360 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
363 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
364 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
365 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
367 hr
= IMFTopology_Clear(topology
);
368 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
370 hr
= IMFTopologyNode_SetTopoNodeID(node
, 123);
371 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
373 IMFTopologyNode_Release(node
);
375 /* Change id for attached node. */
376 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
377 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
379 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
380 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
382 hr
= IMFTopology_AddNode(topology
, node
);
383 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
385 hr
= IMFTopology_AddNode(topology
, node2
);
386 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
388 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
389 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
391 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
392 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
394 hr
= IMFTopology_GetNodeByID(topology
, id
, &node3
);
395 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
396 ok(node3
== node
, "Unexpected node.\n");
397 IMFTopologyNode_Release(node3
);
399 IMFTopologyNode_Release(node
);
400 IMFTopologyNode_Release(node2
);
402 /* Source/output collections. */
403 hr
= IMFTopology_Clear(topology
);
404 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
406 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
407 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
409 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
410 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
411 ok(!!collection
, "Unexpected object pointer.\n");
413 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection2
);
414 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
415 ok(!!collection2
, "Unexpected object pointer.\n");
416 ok(collection2
!= collection
, "Expected cloned collection.\n");
418 hr
= IMFCollection_GetElementCount(collection
, &size
);
419 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
420 ok(!size
, "Unexpected item count.\n");
422 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)collection
);
423 ok(hr
== S_OK
, "Failed to add element, hr %#lx.\n", hr
);
425 hr
= IMFCollection_GetElementCount(collection
, &size
);
426 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
427 ok(size
== 1, "Unexpected item count.\n");
429 hr
= IMFCollection_GetElementCount(collection2
, &size
);
430 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
431 ok(!size
, "Unexpected item count.\n");
433 IMFCollection_Release(collection2
);
434 IMFCollection_Release(collection
);
436 /* Add some nodes. */
437 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
438 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
440 hr
= IMFTopology_GetOutputNodeCollection(topology
, NULL
);
441 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
443 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
444 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
445 hr
= IMFTopology_AddNode(topology
, node
);
446 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
447 IMFTopologyNode_Release(node
);
449 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
450 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
451 ok(!!collection
, "Unexpected object pointer.\n");
452 hr
= IMFCollection_GetElementCount(collection
, &size
);
453 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
454 ok(size
== 1, "Unexpected item count.\n");
455 IMFCollection_Release(collection
);
457 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
458 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
459 hr
= IMFTopology_AddNode(topology
, node
);
460 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
461 IMFTopologyNode_Release(node
);
463 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
464 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
465 ok(!!collection
, "Unexpected object pointer.\n");
466 hr
= IMFCollection_GetElementCount(collection
, &size
);
467 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
468 ok(size
== 1, "Unexpected item count.\n");
469 IMFCollection_Release(collection
);
471 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
472 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
473 hr
= IMFTopology_AddNode(topology
, node
);
474 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
475 IMFTopologyNode_Release(node
);
477 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
478 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
479 ok(!!collection
, "Unexpected object pointer.\n");
480 hr
= IMFCollection_GetElementCount(collection
, &size
);
481 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
482 ok(size
== 1, "Unexpected item count.\n");
483 IMFCollection_Release(collection
);
485 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
486 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
487 hr
= IMFTopology_AddNode(topology
, node
);
488 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
490 /* Associated object. */
491 hr
= IMFTopologyNode_SetObject(node
, NULL
);
492 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
494 hr
= IMFTopologyNode_GetObject(node
, NULL
);
495 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
497 object
= (void *)0xdeadbeef;
498 hr
= IMFTopologyNode_GetObject(node
, &object
);
499 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
500 ok(!object
, "Unexpected object %p.\n", object
);
502 hr
= IMFTopologyNode_SetObject(node
, &test_unk
);
503 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
505 hr
= IMFTopologyNode_GetObject(node
, &object
);
506 ok(hr
== S_OK
, "Failed to get object, hr %#lx.\n", hr
);
507 ok(object
== &test_unk
, "Unexpected object %p.\n", object
);
508 IUnknown_Release(object
);
510 hr
= IMFTopologyNode_SetObject(node
, &test_unk2
);
511 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
513 hr
= IMFTopologyNode_GetCount(node
, &count
);
514 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
515 ok(count
== 0, "Unexpected attribute count %u.\n", count
);
517 hr
= IMFTopologyNode_SetGUID(node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &MF_TOPONODE_TRANSFORM_OBJECTID
);
518 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
520 hr
= IMFTopologyNode_SetObject(node
, NULL
);
521 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
523 object
= (void *)0xdeadbeef;
524 hr
= IMFTopologyNode_GetObject(node
, &object
);
525 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
526 ok(!object
, "Unexpected object %p.\n", object
);
528 hr
= IMFTopologyNode_GetCount(node
, &count
);
529 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
530 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
532 /* Preferred stream types. */
533 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
534 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
535 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
537 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype
);
538 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
540 hr
= MFCreateMediaType(&mediatype
);
541 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
543 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
544 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
546 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
547 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
548 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
549 IMFMediaType_Release(mediatype2
);
551 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
552 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
554 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
555 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
556 ok(!mediatype2
, "Unexpected mediatype instance.\n");
558 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
559 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
561 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
562 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
564 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
565 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
566 ok(io_count
== 2, "Unexpected count %lu.\n", io_count
);
568 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
569 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
570 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
572 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, mediatype
);
573 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
575 IMFTopologyNode_Release(node
);
578 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
579 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
581 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
582 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
584 hr
= IMFTopologyNode_SetOutputPrefType(node
, 2, mediatype
);
585 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
587 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
588 ok(hr
== E_FAIL
, "Failed to get preferred type, hr %#lx.\n", hr
);
589 ok(!mediatype2
, "Unexpected mediatype instance.\n");
591 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
592 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
593 ok(io_count
== 3, "Unexpected count %lu.\n", io_count
);
595 IMFTopologyNode_Release(node
);
598 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
599 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
601 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
602 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
604 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
605 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
606 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
607 IMFMediaType_Release(mediatype2
);
609 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
610 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
612 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
613 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
614 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
616 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
617 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
619 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
620 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
622 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
623 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
625 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
626 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
628 hr
= MFCreateMediaType(&mediatype2
);
629 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
631 /* Changing output type does not change input type. */
632 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype2
);
633 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
635 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype3
);
636 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
637 ok(mediatype3
== mediatype
, "Unexpected mediatype instance.\n");
638 IMFMediaType_Release(mediatype3
);
640 IMFMediaType_Release(mediatype2
);
642 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
643 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
644 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
646 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
647 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
648 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
650 IMFTopologyNode_Release(node
);
652 /* Transform node. */
653 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
654 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
656 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
657 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
659 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
660 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
661 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
663 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
664 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
666 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
667 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
668 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
670 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
671 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
672 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
674 IMFTopologyNode_Release(node
);
676 IMFMediaType_Release(mediatype
);
678 hr
= IMFTopology_GetOutputNodeCollection(topology
, &collection
);
679 ok(hr
== S_OK
|| broken(hr
== E_FAIL
) /* before Win8 */, "Failed to get output node collection, hr %#lx.\n", hr
);
682 ok(!!collection
, "Unexpected object pointer.\n");
683 hr
= IMFCollection_GetElementCount(collection
, &size
);
684 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
685 ok(size
== 1, "Unexpected item count.\n");
686 IMFCollection_Release(collection
);
689 IMFTopology_Release(topology
);
692 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
693 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
695 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
696 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
699 EXPECT_REF(node2
, 1);
701 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
702 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
705 EXPECT_REF(node2
, 2);
707 IMFTopologyNode_Release(node
);
710 EXPECT_REF(node2
, 2);
712 IMFTopologyNode_Release(node2
);
715 EXPECT_REF(node2
, 1);
717 hr
= IMFTopologyNode_GetNodeType(node2
, &node_type
);
718 ok(hr
== S_OK
, "Failed to get node type, hr %#lx.\n", hr
);
720 IMFTopologyNode_Release(node
);
722 /* Connect within topology. */
723 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
724 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
726 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
727 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
729 hr
= MFCreateTopology(&topology
);
730 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
732 hr
= IMFTopology_AddNode(topology
, node
);
733 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
735 hr
= IMFTopology_AddNode(topology
, node2
);
736 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
739 EXPECT_REF(node2
, 2);
741 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
742 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
745 EXPECT_REF(node2
, 3);
747 hr
= IMFTopology_Clear(topology
);
748 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
751 EXPECT_REF(node2
, 1);
753 /* Removing connected node breaks connection. */
754 hr
= IMFTopology_AddNode(topology
, node
);
755 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
757 hr
= IMFTopology_AddNode(topology
, node2
);
758 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
760 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
761 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
763 hr
= IMFTopology_RemoveNode(topology
, node
);
764 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
767 EXPECT_REF(node2
, 2);
769 hr
= IMFTopologyNode_GetOutput(node
, 0, &node3
, &index
);
770 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
772 hr
= IMFTopology_AddNode(topology
, node
);
773 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
775 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
776 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
778 hr
= IMFTopology_RemoveNode(topology
, node2
);
779 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
782 EXPECT_REF(node2
, 1);
784 IMFTopologyNode_Release(node
);
785 IMFTopologyNode_Release(node2
);
787 /* Cloning nodes of different types. */
788 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
789 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
791 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
792 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
794 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
795 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
797 IMFTopologyNode_Release(node2
);
799 /* Cloning preferred types. */
800 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
801 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
803 hr
= MFCreateMediaType(&mediatype
);
804 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
806 hr
= IMFTopologyNode_SetOutputPrefType(node2
, 0, mediatype
);
807 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
809 /* Vista checks for additional attributes. */
810 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
811 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
813 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
814 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
815 ok(mediatype
== mediatype2
, "Unexpected media type.\n");
817 IMFMediaType_Release(mediatype2
);
818 IMFMediaType_Release(mediatype
);
820 IMFTopologyNode_Release(node2
);
822 /* Existing preferred types are not cleared. */
823 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
824 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
826 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
827 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
828 ok(io_count
== 1, "Unexpected output count.\n");
830 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
831 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
833 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
834 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
835 ok(io_count
== 1, "Unexpected output count.\n");
837 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
838 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
839 ok(!!mediatype2
, "Unexpected media type.\n");
840 IMFMediaType_Release(mediatype2
);
842 hr
= IMFTopologyNode_CloneFrom(node2
, node
);
843 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
845 hr
= IMFTopologyNode_GetOutputCount(node2
, &io_count
);
846 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
847 ok(io_count
== 1, "Unexpected output count.\n");
849 IMFTopologyNode_Release(node2
);
850 IMFTopologyNode_Release(node
);
852 /* Add one node, connect to another that hasn't been added. */
853 hr
= IMFTopology_Clear(topology
);
854 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
856 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
857 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
859 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
860 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
862 hr
= IMFTopology_AddNode(topology
, node
);
863 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
865 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
866 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
867 ok(node_count
== 1, "Unexpected node count.\n");
869 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 0);
870 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
872 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
873 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
874 ok(node_count
== 1, "Unexpected node count.\n");
876 IMFTopologyNode_Release(node
);
877 IMFTopologyNode_Release(node2
);
879 /* Add same node to different topologies. */
880 hr
= IMFTopology_Clear(topology
);
881 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
883 hr
= MFCreateTopology(&topology2
);
884 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
886 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
887 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
889 hr
= IMFTopology_AddNode(topology
, node
);
890 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
893 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
894 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
895 ok(node_count
== 1, "Unexpected node count.\n");
897 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
898 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
899 ok(node_count
== 0, "Unexpected node count.\n");
901 hr
= IMFTopology_AddNode(topology2
, node
);
902 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
905 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
906 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
907 ok(node_count
== 1, "Unexpected node count.\n");
909 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
910 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
911 ok(node_count
== 1, "Unexpected node count.\n");
913 IMFTopology_Release(topology2
);
914 IMFTopology_Release(topology
);
917 static void test_topology_tee_node(void)
919 IMFTopologyNode
*src_node
, *tee_node
;
920 IMFMediaType
*mediatype
, *mediatype2
;
921 IMFTopology
*topology
;
925 hr
= MFCreateTopology(&topology
);
926 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
928 hr
= MFCreateMediaType(&mediatype
);
929 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
931 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &tee_node
);
932 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
934 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
935 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
937 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 0, mediatype
);
938 ok(hr
== S_OK
, "Failed to set type, hr %#lx.\n", hr
);
940 /* Even though tee node has only one input and source has only one output,
941 it's possible to connect to higher inputs/outputs. */
943 /* SRC(0) -> TEE(0) */
944 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 0);
945 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
947 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
948 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
949 ok(count
== 1, "Unexpected count %lu.\n", count
);
951 hr
= IMFTopologyNode_GetInputPrefType(tee_node
, 0, &mediatype2
);
952 ok(hr
== S_OK
, "Failed to get type, hr %#lx.\n", hr
);
953 ok(mediatype2
== mediatype
, "Unexpected type.\n");
954 IMFMediaType_Release(mediatype2
);
956 /* SRC(0) -> TEE(1) */
957 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 1);
958 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
960 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
961 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
962 ok(count
== 2, "Unexpected count %lu.\n", count
);
964 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 1, mediatype
);
965 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
967 /* SRC(1) -> TEE(1) */
968 hr
= IMFTopologyNode_ConnectOutput(src_node
, 1, tee_node
, 1);
969 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
971 hr
= IMFTopologyNode_GetOutputCount(src_node
, &count
);
972 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
973 ok(count
== 2, "Unexpected count %lu.\n", count
);
975 IMFMediaType_Release(mediatype
);
976 IMFTopologyNode_Release(src_node
);
977 IMFTopologyNode_Release(tee_node
);
978 IMFTopology_Release(topology
);
981 static HRESULT WINAPI
test_getservice_QI(IMFGetService
*iface
, REFIID riid
, void **obj
)
983 if (IsEqualIID(riid
, &IID_IMFGetService
) || IsEqualIID(riid
, &IID_IUnknown
))
990 return E_NOINTERFACE
;
993 static ULONG WINAPI
test_getservice_AddRef(IMFGetService
*iface
)
998 static ULONG WINAPI
test_getservice_Release(IMFGetService
*iface
)
1003 static HRESULT WINAPI
test_getservice_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
1005 *obj
= (void *)0xdeadbeef;
1009 static const IMFGetServiceVtbl testmfgetservicevtbl
=
1012 test_getservice_AddRef
,
1013 test_getservice_Release
,
1014 test_getservice_GetService
,
1017 static IMFGetService test_getservice
= { &testmfgetservicevtbl
};
1019 static HRESULT WINAPI
testservice_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1021 if (IsEqualIID(riid
, &IID_IUnknown
))
1029 if (IsEqualIID(riid
, &IID_IMFGetService
))
1032 return E_NOINTERFACE
;
1035 static HRESULT WINAPI
testservice2_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1037 if (IsEqualIID(riid
, &IID_IUnknown
))
1043 if (IsEqualIID(riid
, &IID_IMFGetService
))
1045 *obj
= &test_getservice
;
1050 return E_NOINTERFACE
;
1053 static ULONG WINAPI
testservice_AddRef(IUnknown
*iface
)
1058 static ULONG WINAPI
testservice_Release(IUnknown
*iface
)
1063 static const IUnknownVtbl testservicevtbl
=
1067 testservice_Release
,
1070 static const IUnknownVtbl testservice2vtbl
=
1074 testservice_Release
,
1077 static IUnknown testservice
= { &testservicevtbl
};
1078 static IUnknown testservice2
= { &testservice2vtbl
};
1080 static void test_MFGetService(void)
1085 hr
= MFGetService(NULL
, NULL
, NULL
, NULL
);
1086 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1088 unk
= (void *)0xdeadbeef;
1089 hr
= MFGetService(NULL
, NULL
, NULL
, (void **)&unk
);
1090 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1091 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1093 hr
= MFGetService(&testservice
, NULL
, NULL
, NULL
);
1094 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1096 unk
= (void *)0xdeadbeef;
1097 hr
= MFGetService(&testservice
, NULL
, NULL
, (void **)&unk
);
1098 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1099 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1102 hr
= MFGetService(&testservice2
, NULL
, NULL
, (void **)&unk
);
1103 ok(hr
== 0x83eddead, "Unexpected return value %#lx.\n", hr
);
1104 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1107 static void test_sequencer_source(void)
1109 IMFSequencerSource
*seq_source
;
1112 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1113 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1115 hr
= MFCreateSequencerSource(NULL
, &seq_source
);
1116 ok(hr
== S_OK
, "Failed to create sequencer source, hr %#lx.\n", hr
);
1118 check_interface(seq_source
, &IID_IMFMediaSourceTopologyProvider
, TRUE
);
1120 IMFSequencerSource_Release(seq_source
);
1123 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1126 struct test_callback
1128 IMFAsyncCallback IMFAsyncCallback_iface
;
1131 static HRESULT WINAPI
testcallback_QueryInterface(IMFAsyncCallback
*iface
, REFIID riid
, void **obj
)
1133 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
1134 IsEqualIID(riid
, &IID_IUnknown
))
1137 IMFAsyncCallback_AddRef(iface
);
1142 return E_NOINTERFACE
;
1145 static ULONG WINAPI
testcallback_AddRef(IMFAsyncCallback
*iface
)
1150 static ULONG WINAPI
testcallback_Release(IMFAsyncCallback
*iface
)
1155 static HRESULT WINAPI
testcallback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
1157 ok(flags
!= NULL
&& queue
!= NULL
, "Unexpected arguments.\n");
1161 static HRESULT WINAPI
testcallback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1163 ok(result
!= NULL
, "Unexpected result object.\n");
1168 static const IMFAsyncCallbackVtbl testcallbackvtbl
=
1170 testcallback_QueryInterface
,
1171 testcallback_AddRef
,
1172 testcallback_Release
,
1173 testcallback_GetParameters
,
1174 testcallback_Invoke
,
1177 static void init_test_callback(struct test_callback
*callback
)
1179 callback
->IMFAsyncCallback_iface
.lpVtbl
= &testcallbackvtbl
;
1182 static void test_session_events(IMFMediaSession
*session
)
1184 struct test_callback callback
, callback2
;
1185 IMFAsyncResult
*result
;
1186 IMFMediaEvent
*event
;
1189 init_test_callback(&callback
);
1190 init_test_callback(&callback2
);
1192 hr
= IMFMediaSession_GetEvent(session
, MF_EVENT_FLAG_NO_WAIT
, &event
);
1193 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
1196 hr
= IMFMediaSession_BeginGetEvent(session
, NULL
, NULL
);
1197 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1199 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1200 ok(hr
== S_OK
, "Failed to Begin*, hr %#lx.\n", hr
);
1202 /* Same callback, same state. */
1203 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1204 ok(hr
== MF_S_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1206 /* Same callback, different state. */
1207 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1208 ok(hr
== MF_E_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1210 /* Different callback, same state. */
1211 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1212 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1214 /* Different callback, different state. */
1215 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1216 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1218 hr
= MFCreateAsyncResult(NULL
, &callback
.IMFAsyncCallback_iface
, NULL
, &result
);
1219 ok(hr
== S_OK
, "Failed to create result, hr %#lx.\n", hr
);
1221 hr
= IMFMediaSession_EndGetEvent(session
, result
, &event
);
1222 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
1224 /* Shutdown behavior. */
1225 hr
= IMFMediaSession_Shutdown(session
);
1226 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1229 static void test_media_session(void)
1231 IMFRateSupport
*rate_support
;
1232 IMFAttributes
*attributes
;
1233 IMFMediaSession
*session
;
1234 MFSHUTDOWN_STATUS status
;
1235 IMFTopology
*topology
;
1236 IMFShutdown
*shutdown
;
1237 PROPVARIANT propvar
;
1243 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1244 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1246 hr
= MFCreateMediaSession(NULL
, &session
);
1247 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1249 check_interface(session
, &IID_IMFGetService
, TRUE
);
1250 check_interface(session
, &IID_IMFRateSupport
, TRUE
);
1251 check_interface(session
, &IID_IMFRateControl
, TRUE
);
1252 check_interface(session
, &IID_IMFAttributes
, FALSE
);
1253 check_interface(session
, &IID_IMFTopologyNodeAttributeEditor
, FALSE
);
1254 check_interface(session
, &IID_IMFLocalMFTRegistration
, FALSE
);
1255 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
1256 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, TRUE
);
1257 check_service_interface(session
, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE
, &IID_IMFTopologyNodeAttributeEditor
, TRUE
);
1258 check_service_interface(session
, &MF_LOCAL_MFT_REGISTRATION_SERVICE
, &IID_IMFLocalMFTRegistration
, TRUE
);
1260 hr
= IMFMediaSession_GetClock(session
, &clock
);
1261 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1263 hr
= IMFClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
1264 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1266 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1267 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
1269 hr
= IMFMediaSession_Shutdown(session
);
1270 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1272 check_interface(session
, &IID_IMFGetService
, TRUE
);
1274 hr
= IMFMediaSession_QueryInterface(session
, &IID_IMFGetService
, (void **)&gs
);
1275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1277 hr
= IMFGetService_GetService(gs
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1278 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1280 IMFGetService_Release(gs
);
1282 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1283 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1284 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected shutdown status %u.\n", status
);
1286 IMFShutdown_Release(shutdown
);
1288 hr
= IMFMediaSession_ClearTopologies(session
);
1289 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1291 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, NULL
);
1292 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1294 propvar
.vt
= VT_EMPTY
;
1295 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, &propvar
);
1296 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1298 hr
= IMFMediaSession_Pause(session
);
1299 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1301 hr
= IMFMediaSession_Stop(session
);
1302 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1304 hr
= IMFMediaSession_Close(session
);
1305 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1307 hr
= IMFMediaSession_GetClock(session
, &clock
);
1308 ok(hr
== MF_E_SHUTDOWN
|| broken(hr
== E_UNEXPECTED
) /* Win7 */, "Unexpected hr %#lx.\n", hr
);
1310 hr
= IMFMediaSession_GetSessionCapabilities(session
, &caps
);
1311 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1313 hr
= IMFMediaSession_GetSessionCapabilities(session
, NULL
);
1314 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1316 hr
= IMFMediaSession_GetFullTopology(session
, MFSESSION_GETFULLTOPOLOGY_CURRENT
, 0, &topology
);
1317 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1319 hr
= IMFMediaSession_Shutdown(session
);
1320 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1322 IMFMediaSession_Release(session
);
1324 /* Custom topology loader, GUID is not registered. */
1325 hr
= MFCreateAttributes(&attributes
, 1);
1326 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
1328 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_TOPOLOADER
, &MF_SESSION_TOPOLOADER
);
1329 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1331 hr
= MFCreateMediaSession(attributes
, &session
);
1332 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1333 IMFMediaSession_Release(session
);
1335 /* Disabled quality manager. */
1336 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_QUALITY_MANAGER
, &GUID_NULL
);
1337 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1339 hr
= MFCreateMediaSession(attributes
, &session
);
1340 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1341 IMFMediaSession_Release(session
);
1343 IMFAttributes_Release(attributes
);
1345 /* Basic events behavior. */
1346 hr
= MFCreateMediaSession(NULL
, &session
);
1347 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1349 test_session_events(session
);
1351 IMFMediaSession_Release(session
);
1354 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1357 static void test_media_session_rate_control(void)
1359 IMFRateControl
*rate_control
, *clock_rate_control
;
1360 IMFPresentationClock
*presentation_clock
;
1361 IMFPresentationTimeSource
*time_source
;
1362 MFCLOCK_PROPERTIES clock_props
;
1363 IMFRateSupport
*rate_support
;
1364 IMFMediaSession
*session
;
1370 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1371 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1373 hr
= MFCreateMediaSession(NULL
, &session
);
1374 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1376 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1377 ok(hr
== S_OK
, "Failed to get rate support interface, hr %#lx.\n", hr
);
1379 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, (void **)&rate_control
);
1380 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
1382 hr
= IMFRateControl_GetRate(rate_control
, NULL
, NULL
);
1383 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1386 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
1387 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1388 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1390 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
1391 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1395 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
1396 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1397 ok(!thin
, "Unexpected thinning.\n");
1398 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1400 hr
= IMFMediaSession_GetClock(session
, &clock
);
1401 ok(hr
== S_OK
, "Failed to get clock, hr %#lx.\n", hr
);
1403 hr
= IMFClock_QueryInterface(clock
, &IID_IMFPresentationClock
, (void **)&presentation_clock
);
1404 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1406 hr
= IMFClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&clock_rate_control
);
1407 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1410 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1411 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1412 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1414 hr
= IMFRateControl_SetRate(clock_rate_control
, FALSE
, 1.5f
);
1415 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1417 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1418 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1420 hr
= IMFClock_GetProperties(clock
, &clock_props
);
1421 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1423 hr
= MFCreateSystemTimeSource(&time_source
);
1424 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
1426 hr
= IMFPresentationClock_SetTimeSource(presentation_clock
, time_source
);
1427 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
1429 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1430 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1433 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1434 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1435 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1437 IMFPresentationTimeSource_Release(time_source
);
1439 IMFRateControl_Release(clock_rate_control
);
1440 IMFPresentationClock_Release(presentation_clock
);
1441 IMFClock_Release(clock
);
1443 IMFRateControl_Release(rate_control
);
1444 IMFRateSupport_Release(rate_support
);
1446 IMFMediaSession_Release(session
);
1449 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1452 static HRESULT WINAPI
test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
,
1455 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
1456 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
1457 IsEqualIID(riid
, &IID_IUnknown
))
1460 IMFSampleGrabberSinkCallback_AddRef(iface
);
1465 return E_NOINTERFACE
;
1468 static ULONG WINAPI
test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
1473 static ULONG WINAPI
test_grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
1478 static HRESULT WINAPI
test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
,
1484 static HRESULT WINAPI
test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1489 static HRESULT WINAPI
test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1494 static HRESULT WINAPI
test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1499 static HRESULT WINAPI
test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
, float rate
)
1504 static HRESULT WINAPI
test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
1505 IMFPresentationClock
*clock
)
1510 static HRESULT WINAPI
test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
1511 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
1516 static HRESULT WINAPI
test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
1521 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl
=
1523 test_grabber_callback_QueryInterface
,
1524 test_grabber_callback_AddRef
,
1525 test_grabber_callback_Release
,
1526 test_grabber_callback_OnClockStart
,
1527 test_grabber_callback_OnClockStop
,
1528 test_grabber_callback_OnClockPause
,
1529 test_grabber_callback_OnClockRestart
,
1530 test_grabber_callback_OnClockSetRate
,
1531 test_grabber_callback_OnSetPresentationClock
,
1532 test_grabber_callback_OnProcessSample
,
1533 test_grabber_callback_OnShutdown
,
1538 IMFMediaSource IMFMediaSource_iface
;
1542 static struct test_source
*impl_from_IMFMediaSource(IMFMediaSource
*iface
)
1544 return CONTAINING_RECORD(iface
, struct test_source
, IMFMediaSource_iface
);
1547 static HRESULT WINAPI
test_source_QueryInterface(IMFMediaSource
*iface
, REFIID riid
, void **out
)
1549 if (IsEqualIID(riid
, &IID_IMFMediaSource
)
1550 || IsEqualIID(riid
, &IID_IMFMediaEventGenerator
)
1551 || IsEqualIID(riid
, &IID_IUnknown
))
1558 return E_NOINTERFACE
;
1561 IMFMediaSource_AddRef(iface
);
1565 static ULONG WINAPI
test_source_AddRef(IMFMediaSource
*iface
)
1567 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1568 return InterlockedIncrement(&source
->refcount
);
1571 static ULONG WINAPI
test_source_Release(IMFMediaSource
*iface
)
1573 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1574 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
1582 static HRESULT WINAPI
test_source_GetEvent(IMFMediaSource
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1584 ok(0, "Unexpected call.\n");
1588 static HRESULT WINAPI
test_source_BeginGetEvent(IMFMediaSource
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
1590 ok(0, "Unexpected call.\n");
1594 static HRESULT WINAPI
test_source_EndGetEvent(IMFMediaSource
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
1596 ok(0, "Unexpected call.\n");
1600 static HRESULT WINAPI
test_source_QueueEvent(IMFMediaSource
*iface
, MediaEventType event_type
, REFGUID ext_type
,
1601 HRESULT hr
, const PROPVARIANT
*value
)
1603 ok(0, "Unexpected call.\n");
1607 static HRESULT WINAPI
test_source_GetCharacteristics(IMFMediaSource
*iface
, DWORD
*flags
)
1609 ok(0, "Unexpected call.\n");
1613 static HRESULT WINAPI
test_source_CreatePresentationDescriptor(IMFMediaSource
*iface
, IMFPresentationDescriptor
**pd
)
1615 ok(0, "Unexpected call.\n");
1619 static HRESULT WINAPI
test_source_Start(IMFMediaSource
*iface
, IMFPresentationDescriptor
*pd
, const GUID
*time_format
,
1620 const PROPVARIANT
*start_position
)
1622 ok(0, "Unexpected call.\n");
1626 static HRESULT WINAPI
test_source_Stop(IMFMediaSource
*iface
)
1628 ok(0, "Unexpected call.\n");
1632 static HRESULT WINAPI
test_source_Pause(IMFMediaSource
*iface
)
1634 ok(0, "Unexpected call.\n");
1638 static HRESULT WINAPI
test_source_Shutdown(IMFMediaSource
*iface
)
1640 ok(0, "Unexpected call.\n");
1644 static const IMFMediaSourceVtbl test_source_vtbl
=
1646 test_source_QueryInterface
,
1648 test_source_Release
,
1649 test_source_GetEvent
,
1650 test_source_BeginGetEvent
,
1651 test_source_EndGetEvent
,
1652 test_source_QueueEvent
,
1653 test_source_GetCharacteristics
,
1654 test_source_CreatePresentationDescriptor
,
1658 test_source_Shutdown
,
1661 static IMFMediaSource
*create_test_source(void)
1663 struct test_source
*source
;
1665 source
= calloc(1, sizeof(*source
));
1666 source
->IMFMediaSource_iface
.lpVtbl
= &test_source_vtbl
;
1667 source
->refcount
= 1;
1669 return &source
->IMFMediaSource_iface
;
1672 static void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
1677 hr
= IMFMediaType_DeleteAllItems(mediatype
);
1678 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1680 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
1682 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
1683 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
1687 static void init_source_node(IMFMediaType
*mediatype
, IMFMediaSource
*source
, IMFTopologyNode
*node
)
1689 IMFPresentationDescriptor
*pd
;
1690 IMFMediaTypeHandler
*handler
;
1691 IMFStreamDescriptor
*sd
;
1694 hr
= IMFTopologyNode_DeleteAllItems(node
);
1695 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1697 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
1698 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
1700 hr
= IMFStreamDescriptor_GetMediaTypeHandler(sd
, &handler
);
1701 ok(hr
== S_OK
, "Failed to get media type handler, hr %#lx.\n", hr
);
1703 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
1704 ok(hr
== S_OK
, "Failed to set current media type, hr %#lx.\n", hr
);
1706 IMFMediaTypeHandler_Release(handler
);
1708 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
1709 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
1711 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
1712 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
1714 IMFPresentationDescriptor_Release(pd
);
1716 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
1717 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
1721 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
1722 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1725 IMFStreamDescriptor_Release(sd
);
1728 static void init_sink_node(IMFActivate
*sink_activate
, unsigned int method
, IMFTopologyNode
*node
)
1730 IMFStreamSink
*stream_sink
;
1734 hr
= IMFTopologyNode_DeleteAllItems(node
);
1735 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1737 hr
= IMFActivate_ActivateObject(sink_activate
, &IID_IMFMediaSink
, (void **)&sink
);
1738 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
1740 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
1741 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1743 IMFMediaSink_Release(sink
);
1745 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)stream_sink
);
1746 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
1748 IMFStreamSink_Release(stream_sink
);
1750 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_CONNECT_METHOD
, method
);
1751 ok(hr
== S_OK
, "Failed to set connect method, hr %#lx.\n", hr
);
1754 enum loader_test_flags
1756 LOADER_EXPECTED_DECODER
= 0x1,
1757 LOADER_EXPECTED_CONVERTER
= 0x2,
1761 static void test_topology_loader(void)
1763 static const struct loader_test
1765 media_type_desc input_type
;
1766 media_type_desc output_type
;
1767 MF_CONNECT_METHOD method
;
1768 HRESULT expected_result
;
1774 /* PCM -> PCM, same type */
1776 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1777 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1778 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1779 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1780 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1781 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1782 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1785 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1786 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1787 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1788 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1789 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1790 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1791 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1799 /* PCM -> PCM, different bps. */
1801 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1802 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1803 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1804 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1805 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1806 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1807 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1810 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1811 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1812 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1813 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1814 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000),
1815 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1816 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1820 MF_E_INVALIDMEDIATYPE
,
1824 /* PCM -> PCM, different bps. */
1826 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1827 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1828 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1829 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1830 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1831 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1832 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1835 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1836 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1837 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1838 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1839 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000),
1840 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1841 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1844 MF_CONNECT_ALLOW_CONVERTER
,
1846 LOADER_EXPECTED_CONVERTER
| LOADER_TODO
,
1852 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1853 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
1854 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
1855 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1856 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
1857 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1860 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1861 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1862 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1863 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1864 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1865 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1866 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1870 MF_E_INVALIDMEDIATYPE
,
1876 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1877 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
1878 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
1879 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1880 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
1881 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1884 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1885 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1886 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1887 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1888 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1889 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1890 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1893 MF_CONNECT_ALLOW_CONVERTER
,
1894 MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION
,
1901 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1902 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
1903 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
1904 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1905 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
1906 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1909 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1910 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1911 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1912 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1913 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1914 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1915 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1918 MF_CONNECT_ALLOW_DECODER
,
1920 LOADER_EXPECTED_DECODER
| LOADER_TODO
,
1924 IMFSampleGrabberSinkCallback test_grabber_callback
= { &test_grabber_callback_vtbl
};
1925 IMFTopologyNode
*src_node
, *sink_node
, *src_node2
, *sink_node2
, *mft_node
;
1926 IMFTopology
*topology
, *topology2
, *full_topology
;
1927 IMFMediaType
*media_type
, *input_type
, *output_type
;
1928 IMFPresentationDescriptor
*pd
;
1929 unsigned int i
, count
, value
;
1930 IMFActivate
*sink_activate
;
1931 MF_TOPOLOGY_TYPE node_type
;
1932 IMFStreamDescriptor
*sd
;
1933 IMFTransform
*transform
;
1934 IMFMediaSource
*source
;
1935 IMFTopoLoader
*loader
;
1936 IUnknown
*node_object
;
1943 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1944 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1946 hr
= MFCreateTopoLoader(NULL
);
1947 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1949 hr
= MFCreateTopoLoader(&loader
);
1950 ok(hr
== S_OK
, "Failed to create topology loader, hr %#lx.\n", hr
);
1952 hr
= MFCreateTopology(&topology
);
1953 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
1955 /* Empty topology */
1956 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
1958 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
1960 /* Add source node. */
1961 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
1962 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1964 /* When a decoder is involved, windows requires this attribute to be present */
1965 source
= create_test_source();
1967 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
1968 ok(hr
== S_OK
, "Failed to set node source, hr %#lx.\n", hr
);
1970 hr
= MFCreateMediaType(&media_type
);
1971 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1973 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
1974 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1975 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
1976 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1978 hr
= MFCreateStreamDescriptor(0, 1, &media_type
, &sd
);
1979 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
1981 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
1982 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
1984 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
1985 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
1987 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
1988 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
1990 IMFPresentationDescriptor_Release(pd
);
1991 IMFStreamDescriptor_Release(sd
);
1992 IMFMediaType_Release(media_type
);
1994 hr
= IMFTopology_AddNode(topology
, src_node
);
1995 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1997 /* Source node only. */
1998 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2000 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2002 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &sink_node
);
2003 ok(hr
== S_OK
, "Failed to create output node, hr %#lx.\n", hr
);
2005 hr
= MFCreateMediaType(&media_type
);
2006 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2008 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2009 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2010 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2011 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2013 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &test_grabber_callback
, &sink_activate
);
2014 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2016 hr
= IMFTopologyNode_SetObject(sink_node
, (IUnknown
*)sink_activate
);
2017 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
2019 IMFMediaType_Release(media_type
);
2021 hr
= IMFTopology_AddNode(topology
, sink_node
);
2022 ok(hr
== S_OK
, "Failed to add sink node, hr %#lx.\n", hr
);
2024 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2026 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2028 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, sink_node
, 0);
2029 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
2031 /* Sink was not resolved. */
2032 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2033 ok(hr
== MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2035 hr
= MFCreateMediaType(&input_type
);
2036 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2038 hr
= MFCreateMediaType(&output_type
);
2039 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2041 for (i
= 0; i
< ARRAY_SIZE(loader_tests
); ++i
)
2043 const struct loader_test
*test
= &loader_tests
[i
];
2045 init_media_type(input_type
, test
->input_type
, -1);
2046 init_media_type(output_type
, test
->output_type
, -1);
2048 hr
= MFCreateSampleGrabberSinkActivate(output_type
, &test_grabber_callback
, &sink_activate
);
2049 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2051 init_source_node(input_type
, source
, src_node
);
2052 init_sink_node(sink_activate
, test
->method
, sink_node
);
2054 hr
= IMFTopology_GetCount(topology
, &count
);
2055 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2056 ok(!count
, "Unexpected count %u.\n", count
);
2058 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2059 todo_wine_if(test
->flags
& LOADER_TODO
)
2060 ok(hr
== test
->expected_result
, "Unexpected hr %#lx on test %u.\n", hr
, i
);
2061 ok(full_topology
!= topology
, "Unexpected instance.\n");
2063 if (test
->expected_result
== S_OK
&& hr
== S_OK
)
2065 hr
= IMFTopology_GetCount(full_topology
, &count
);
2066 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2068 ok(count
== 1, "Unexpected count %u.\n", count
);
2071 hr
= IMFTopology_GetUINT32(full_topology
, &MF_TOPOLOGY_RESOLUTION_STATUS
, &value
);
2073 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2074 ok(value
== MF_TOPOLOGY_RESOLUTION_SUCCEEDED
, "Unexpected value %#x.\n", value
);
2077 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2079 if (test
->flags
& LOADER_EXPECTED_CONVERTER
)
2082 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2083 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
2084 todo_wine_if(test
->flags
& (LOADER_EXPECTED_CONVERTER
| LOADER_EXPECTED_DECODER
))
2085 ok(node_count
== count
, "Unexpected node count %u.\n", node_count
);
2087 hr
= IMFTopologyNode_GetTopoNodeID(src_node
, &node_id
);
2088 ok(hr
== S_OK
, "Failed to get source node id, hr %#lx.\n", hr
);
2090 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &src_node2
);
2091 ok(hr
== S_OK
, "Failed to get source in resolved topology, hr %#lx.\n", hr
);
2093 hr
= IMFTopologyNode_GetTopoNodeID(sink_node
, &node_id
);
2094 ok(hr
== S_OK
, "Failed to get sink node id, hr %#lx.\n", hr
);
2096 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &sink_node2
);
2097 ok(hr
== S_OK
, "Failed to get sink in resolved topology, hr %#lx.\n", hr
);
2099 if (test
->flags
& (LOADER_EXPECTED_DECODER
| LOADER_EXPECTED_CONVERTER
) && strcmp(winetest_platform
, "wine"))
2101 hr
= IMFTopologyNode_GetOutput(src_node2
, 0, &mft_node
, &index
);
2102 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2103 ok(!index
, "Unexpected stream index %lu.\n", index
);
2105 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2106 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2107 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2109 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2110 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2112 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2115 hr
= IMFTopologyNode_GetUINT32(mft_node
, &MF_TOPONODE_DECODER
, &value
);
2116 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2117 ok(value
== 1, "Unexpected value.\n");
2120 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2121 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2123 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void **)&transform
);
2124 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2125 IUnknown_Release(node_object
);
2127 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
2128 ok(hr
== S_OK
, "Failed to get transform input type, hr %#lx.\n", hr
);
2130 hr
= IMFMediaType_Compare(input_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2131 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2132 ok(ret
, "Input type of first transform doesn't match source node type.\n");
2134 IMFTopologyNode_Release(mft_node
);
2135 IMFMediaType_Release(media_type
);
2136 IMFTransform_Release(transform
);
2138 hr
= IMFTopologyNode_GetInput(sink_node2
, 0, &mft_node
, &index
);
2139 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2140 ok(!index
, "Unexpected stream index %lu.\n", index
);
2142 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2143 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2144 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2146 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2147 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2149 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2150 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2152 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void**) &transform
);
2153 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2154 IUnknown_Release(node_object
);
2156 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
2157 ok(hr
== S_OK
, "Failed to get transform output type, hr %#lx.\n", hr
);
2159 hr
= IMFMediaType_Compare(output_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2160 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2161 ok(ret
, "Output type of last transform doesn't match sink node type.\n");
2163 IMFTopologyNode_Release(mft_node
);
2164 IMFMediaType_Release(media_type
);
2165 IMFTransform_Release(transform
);
2168 IMFTopologyNode_Release(sink_node2
);
2170 hr
= IMFTopology_SetUINT32(full_topology
, &IID_IMFTopology
, 123);
2171 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2172 hr
= IMFTopoLoader_Load(loader
, full_topology
, &topology2
, NULL
);
2173 ok(hr
== S_OK
, "Failed to resolve topology, hr %#lx.\n", hr
);
2174 ok(full_topology
!= topology2
, "Unexpected instance.\n");
2175 hr
= IMFTopology_GetUINT32(topology2
, &IID_IMFTopology
, &value
);
2176 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2178 IMFTopology_Release(topology2
);
2179 IMFTopology_Release(full_topology
);
2182 hr
= IMFTopology_GetCount(topology
, &count
);
2183 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2184 ok(!count
, "Unexpected count %u.\n", count
);
2186 IMFActivate_ShutdownObject(sink_activate
);
2187 IMFActivate_Release(sink_activate
);
2190 IMFMediaType_Release(input_type
);
2191 IMFMediaType_Release(output_type
);
2193 IMFMediaSource_Release(source
);
2194 IMFTopoLoader_Release(loader
);
2197 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
2200 static void test_topology_loader_evr(void)
2202 IMFTopologyNode
*node
, *source_node
, *evr_node
;
2203 IMFTopology
*topology
, *full_topology
;
2204 IMFMediaTypeHandler
*handler
;
2205 unsigned int i
, count
, value
;
2206 IMFStreamSink
*stream_sink
;
2207 IMFMediaType
*media_type
;
2208 IMFActivate
*activate
;
2209 IMFTopoLoader
*loader
;
2216 hr
= CoInitialize(NULL
);
2217 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2219 hr
= MFCreateTopoLoader(&loader
);
2220 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2223 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &source_node
);
2224 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2226 hr
= MFCreateMediaType(&media_type
);
2227 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2229 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
2230 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2231 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
2232 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2233 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
2234 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2235 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
2236 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2238 init_source_node(media_type
, NULL
, source_node
);
2240 /* EVR sink node. */
2241 window
= create_window();
2243 hr
= MFCreateVideoRendererActivate(window
, &activate
);
2244 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
2246 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2247 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2249 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
2250 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2252 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &evr_node
);
2253 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2255 hr
= IMFTopologyNode_SetObject(evr_node
, (IUnknown
*)stream_sink
);
2256 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2258 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
2259 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2260 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
2261 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2262 IMFMediaTypeHandler_Release(handler
);
2264 IMFStreamSink_Release(stream_sink
);
2265 IMFMediaSink_Release(sink
);
2267 hr
= MFCreateTopology(&topology
);
2268 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2270 hr
= IMFTopology_AddNode(topology
, source_node
);
2271 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2272 hr
= IMFTopology_AddNode(topology
, evr_node
);
2273 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2274 hr
= IMFTopologyNode_ConnectOutput(source_node
, 0, evr_node
, 0);
2275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2277 hr
= IMFTopologyNode_SetUINT32(evr_node
, &MF_TOPONODE_CONNECT_METHOD
, MF_CONNECT_DIRECT
);
2278 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2280 hr
= IMFTopologyNode_GetCount(evr_node
, &count
);
2281 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2282 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
2284 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2285 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2287 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2288 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2289 ok(node_count
== 3, "Unexpected node count %u.\n", node_count
);
2291 for (i
= 0; i
< node_count
; ++i
)
2293 MF_TOPOLOGY_TYPE node_type
;
2295 hr
= IMFTopology_GetNode(full_topology
, i
, &node
);
2296 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2298 hr
= IMFTopologyNode_GetNodeType(node
, &node_type
);
2299 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2301 if (node_type
== MF_TOPOLOGY_OUTPUT_NODE
)
2304 hr
= IMFTopologyNode_GetUINT32(node
, &MF_TOPONODE_STREAMID
, &value
);
2305 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2306 ok(!value
, "Unexpected stream id %u.\n", value
);
2308 else if (node_type
== MF_TOPOLOGY_SOURCESTREAM_NODE
)
2311 hr
= IMFTopologyNode_GetUINT64(node
, &MF_TOPONODE_MEDIASTART
, &value64
);
2312 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2313 ok(!value64
, "Unexpected value.\n");
2317 IMFTopology_Release(full_topology
);
2319 IMFTopoLoader_Release(loader
);
2321 IMFTopologyNode_Release(source_node
);
2322 IMFTopologyNode_Release(evr_node
);
2323 IMFTopology_Release(topology
);
2324 IMFMediaType_Release(media_type
);
2325 DestroyWindow(window
);
2330 static HRESULT WINAPI
testshutdown_QueryInterface(IMFShutdown
*iface
, REFIID riid
, void **obj
)
2332 if (IsEqualIID(riid
, &IID_IMFShutdown
) ||
2333 IsEqualIID(riid
, &IID_IUnknown
))
2336 IMFShutdown_AddRef(iface
);
2341 return E_NOINTERFACE
;
2344 static ULONG WINAPI
testshutdown_AddRef(IMFShutdown
*iface
)
2349 static ULONG WINAPI
testshutdown_Release(IMFShutdown
*iface
)
2354 static HRESULT WINAPI
testshutdown_Shutdown(IMFShutdown
*iface
)
2359 static HRESULT WINAPI
testshutdown_GetShutdownStatus(IMFShutdown
*iface
, MFSHUTDOWN_STATUS
*status
)
2361 ok(0, "Unexpected call.\n");
2365 static const IMFShutdownVtbl testshutdownvtbl
=
2367 testshutdown_QueryInterface
,
2368 testshutdown_AddRef
,
2369 testshutdown_Release
,
2370 testshutdown_Shutdown
,
2371 testshutdown_GetShutdownStatus
,
2374 static void test_MFShutdownObject(void)
2376 IMFShutdown testshutdown
= { &testshutdownvtbl
};
2377 IUnknown testshutdown2
= { &testservicevtbl
};
2380 hr
= MFShutdownObject(NULL
);
2381 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2383 hr
= MFShutdownObject((IUnknown
*)&testshutdown
);
2384 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2386 hr
= MFShutdownObject(&testshutdown2
);
2387 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2397 static HRESULT WINAPI
test_clock_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **obj
)
2399 if (IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2400 IsEqualIID(riid
, &IID_IUnknown
))
2403 IMFClockStateSink_AddRef(iface
);
2408 return E_NOINTERFACE
;
2411 static ULONG WINAPI
test_clock_sink_AddRef(IMFClockStateSink
*iface
)
2416 static ULONG WINAPI
test_clock_sink_Release(IMFClockStateSink
*iface
)
2421 static HRESULT WINAPI
test_clock_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
, LONGLONG offset
)
2426 static HRESULT WINAPI
test_clock_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
2431 static HRESULT WINAPI
test_clock_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
2436 static HRESULT WINAPI
test_clock_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
2441 static HRESULT WINAPI
test_clock_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
2446 static const IMFClockStateSinkVtbl test_clock_sink_vtbl
=
2448 test_clock_sink_QueryInterface
,
2449 test_clock_sink_AddRef
,
2450 test_clock_sink_Release
,
2451 test_clock_sink_OnClockStart
,
2452 test_clock_sink_OnClockStop
,
2453 test_clock_sink_OnClockPause
,
2454 test_clock_sink_OnClockRestart
,
2455 test_clock_sink_OnClockSetRate
,
2458 static void test_presentation_clock(void)
2460 static const struct clock_state_test
2462 enum clock_action action
;
2463 MFCLOCK_STATE clock_state
;
2464 MFCLOCK_STATE source_state
;
2467 clock_state_change
[] =
2469 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
},
2470 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_INVALIDREQUEST
},
2471 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_CLOCK_STATE_ALREADY_SET
},
2472 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2473 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2474 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2475 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2476 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2477 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2478 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2479 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2480 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_INVALIDREQUEST
},
2481 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2482 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2483 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2485 IMFClockStateSink test_sink
= { &test_clock_sink_vtbl
};
2486 IMFPresentationTimeSource
*time_source
;
2487 MFCLOCK_PROPERTIES props
, props2
;
2488 IMFRateControl
*rate_control
;
2489 IMFPresentationClock
*clock
;
2490 MFSHUTDOWN_STATUS status
;
2491 IMFShutdown
*shutdown
;
2492 MFTIME systime
, time
;
2493 LONGLONG clock_time
;
2494 MFCLOCK_STATE state
;
2501 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2502 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
2504 hr
= MFCreatePresentationClock(&clock
);
2505 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
2507 check_interface(clock
, &IID_IMFTimer
, TRUE
);
2508 check_interface(clock
, &IID_IMFRateControl
, TRUE
);
2509 check_interface(clock
, &IID_IMFPresentationClock
, TRUE
);
2510 check_interface(clock
, &IID_IMFShutdown
, TRUE
);
2511 check_interface(clock
, &IID_IMFClock
, TRUE
);
2513 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&rate_control
);
2514 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
2516 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2517 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2519 hr
= IMFPresentationClock_GetTimeSource(clock
, NULL
);
2520 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2522 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2523 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2525 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, NULL
);
2526 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2528 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2529 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2531 hr
= IMFPresentationClock_GetTime(clock
, NULL
);
2532 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2535 hr
= IMFPresentationClock_GetContinuityKey(clock
, &value
);
2536 ok(hr
== S_OK
, "Failed to get continuity key, hr %#lx.\n", hr
);
2537 ok(value
== 0, "Unexpected value %lu.\n", value
);
2539 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2540 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2542 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2543 ok(hr
== S_OK
, "Failed to get state, hr %#lx.\n", hr
);
2544 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2546 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &clock_time
, &systime
);
2547 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2549 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, NULL
, &systime
);
2550 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2552 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, NULL
);
2553 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2556 hr
= IMFPresentationClock_AddClockStateSink(clock
, NULL
);
2557 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2559 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2560 ok(hr
== S_OK
, "Failed to add a sink, hr %#lx.\n", hr
);
2562 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2563 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2565 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, NULL
);
2566 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2568 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2569 ok(hr
== S_OK
, "Failed to remove sink, hr %#lx.\n", hr
);
2571 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2572 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2574 /* State change commands, time source is not set yet. */
2575 hr
= IMFPresentationClock_Start(clock
, 0);
2576 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2578 hr
= IMFPresentationClock_Pause(clock
);
2579 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2581 hr
= IMFPresentationClock_Stop(clock
);
2582 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2584 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2585 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2587 /* Set default time source. */
2588 hr
= MFCreateSystemTimeSource(&time_source
);
2589 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
2591 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &value
);
2592 ok(hr
== S_OK
, "Failed to get time source flags, hr %#lx.\n", hr
);
2593 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2594 "Unexpected clock flags %#lx.\n", value
);
2596 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
2597 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
2599 hr
= IMFPresentationTimeSource_GetProperties(time_source
, &props2
);
2600 ok(hr
== S_OK
, "Failed to get time source properties, hr %#lx.\n", hr
);
2602 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2603 ok(hr
== S_OK
, "Failed to get clock flags, hr %#lx.\n", hr
);
2604 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2605 "Unexpected clock flags %#lx.\n", value
);
2607 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2608 ok(hr
== S_OK
, "Failed to get clock properties, hr %#lx.\n", hr
);
2609 ok(!memcmp(&props
, &props2
, sizeof(props
)), "Unexpected clock properties.\n");
2611 /* Changing rate at initial state. */
2612 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2613 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2614 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2616 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2617 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2618 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2619 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2620 ok(rate
== 0.0f
, "Unexpected rate.\n");
2621 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2622 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2624 /* State changes. */
2625 for (i
= 0; i
< ARRAY_SIZE(clock_state_change
); ++i
)
2627 switch (clock_state_change
[i
].action
)
2630 hr
= IMFPresentationClock_Stop(clock
);
2633 hr
= IMFPresentationClock_Pause(clock
);
2636 hr
= IMFPresentationClock_Start(clock
, 0);
2641 ok(hr
== clock_state_change
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
2643 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
2644 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
2645 ok(state
== clock_state_change
[i
].source_state
, "%u: unexpected state %d.\n", i
, state
);
2647 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2648 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
2649 ok(state
== clock_state_change
[i
].clock_state
, "%u: unexpected state %d.\n", i
, state
);
2652 /* Clock time stamps. */
2653 hr
= IMFPresentationClock_Start(clock
, 10);
2654 ok(hr
== S_OK
, "Failed to start presentation clock, hr %#lx.\n", hr
);
2656 hr
= IMFPresentationClock_Pause(clock
);
2657 ok(hr
== S_OK
, "Failed to pause presentation clock, hr %#lx.\n", hr
);
2659 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2660 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
2662 hr
= IMFPresentationTimeSource_GetCorrelatedTime(time_source
, 0, &clock_time
, &systime
);
2663 ok(hr
== S_OK
, "Failed to get time source time, hr %#lx.\n", hr
);
2664 ok(time
== clock_time
, "Unexpected clock time.\n");
2666 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, &systime
);
2667 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
2668 ok(time
== clock_time
, "Unexpected clock time.\n");
2670 IMFPresentationTimeSource_Release(time_source
);
2672 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
2673 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2675 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
2676 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2678 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2679 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2680 ok(rate
== 1.0f
, "Unexpected rate.\n");
2681 ok(!thin
, "Unexpected thinning.\n");
2683 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2684 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2685 ok(state
== MFCLOCK_STATE_PAUSED
, "Unexpected state %d.\n", state
);
2687 hr
= IMFPresentationClock_Start(clock
, 0);
2688 ok(hr
== S_OK
, "Failed to stop, hr %#lx.\n", hr
);
2690 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2691 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2692 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2693 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2694 ok(rate
== 0.0f
, "Unexpected rate.\n");
2695 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2696 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2697 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2698 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2699 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.5f
);
2700 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2701 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, -1.0f
);
2702 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2703 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 0.0f
);
2704 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2705 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 1.0f
);
2706 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2708 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2709 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2710 ok(state
== MFCLOCK_STATE_RUNNING
, "Unexpected state %d.\n", state
);
2712 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2713 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2714 ok(rate
== 0.5f
, "Unexpected rate.\n");
2715 ok(!thin
, "Unexpected thinning.\n");
2717 IMFRateControl_Release(rate_control
);
2719 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
2720 ok(hr
== S_OK
, "Failed to get shutdown interface, hr %#lx.\n", hr
);
2722 /* Shutdown behavior. */
2723 hr
= IMFShutdown_GetShutdownStatus(shutdown
, NULL
);
2724 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2726 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2727 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
2729 hr
= IMFShutdown_Shutdown(shutdown
);
2730 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2733 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2734 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2735 ok(!!time_source
, "Unexpected instance %p.\n", time_source
);
2736 IMFPresentationTimeSource_Release(time_source
);
2738 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2739 ok(hr
== S_OK
, "Failed to get time, hr %#lx.\n", hr
);
2741 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2742 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
2743 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2745 hr
= IMFPresentationClock_Start(clock
, 0);
2746 ok(hr
== S_OK
, "Failed to start the clock, hr %#lx.\n", hr
);
2748 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2749 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
2750 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2752 hr
= IMFShutdown_Shutdown(shutdown
);
2753 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2755 IMFShutdown_Release(shutdown
);
2757 IMFPresentationClock_Release(clock
);
2760 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2763 static HRESULT WINAPI
grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
, void **obj
)
2765 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
2766 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2767 IsEqualIID(riid
, &IID_IUnknown
))
2770 IMFSampleGrabberSinkCallback_AddRef(iface
);
2775 return E_NOINTERFACE
;
2778 static ULONG WINAPI
grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
2783 static ULONG WINAPI
grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
2788 static HRESULT WINAPI
grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, LONGLONG offset
)
2793 static HRESULT WINAPI
grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2798 static HRESULT WINAPI
grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2803 static HRESULT WINAPI
grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2808 static HRESULT WINAPI
grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, float rate
)
2813 static HRESULT WINAPI
grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
2814 IMFPresentationClock
*clock
)
2819 static HRESULT WINAPI
grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
2820 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
2825 static HRESULT WINAPI
grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
2830 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl
=
2832 grabber_callback_QueryInterface
,
2833 grabber_callback_AddRef
,
2834 grabber_callback_Release
,
2835 grabber_callback_OnClockStart
,
2836 grabber_callback_OnClockStop
,
2837 grabber_callback_OnClockPause
,
2838 grabber_callback_OnClockRestart
,
2839 grabber_callback_OnClockSetRate
,
2840 grabber_callback_OnSetPresentationClock
,
2841 grabber_callback_OnProcessSample
,
2842 grabber_callback_OnShutdown
,
2845 static IMFSampleGrabberSinkCallback grabber_callback
= { &grabber_callback_vtbl
};
2847 static void test_sample_grabber(void)
2849 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
2850 IMFMediaTypeHandler
*handler
, *handler2
;
2851 IMFPresentationTimeSource
*time_source
;
2852 IMFPresentationClock
*clock
, *clock2
;
2853 IMFStreamSink
*stream
, *stream2
;
2854 IMFRateSupport
*rate_support
;
2855 IMFMediaEventGenerator
*eg
;
2856 IMFMediaSink
*sink
, *sink2
;
2857 DWORD flags
, count
, id
;
2858 IMFActivate
*activate
;
2859 IMFMediaEvent
*event
;
2867 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2868 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
2870 hr
= MFCreateMediaType(&media_type
);
2871 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2873 hr
= MFCreateSampleGrabberSinkActivate(NULL
, NULL
, &activate
);
2874 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2876 hr
= MFCreateSampleGrabberSinkActivate(NULL
, &grabber_callback
, &activate
);
2877 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2879 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2880 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2881 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2882 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2884 EXPECT_REF(media_type
, 1);
2885 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
2886 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
2887 EXPECT_REF(media_type
, 2);
2889 hr
= IMFActivate_GetCount(activate
, &attr_count
);
2890 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2891 ok(!attr_count
, "Unexpected count %u.\n", attr_count
);
2893 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2894 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
2896 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
2897 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
2898 check_interface(sink
, &IID_IMFGetService
, TRUE
);
2899 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
2900 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
2902 if (SUCCEEDED(MFGetService((IUnknown
*)sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
)))
2904 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
2905 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2906 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
2908 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
2909 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2910 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
2912 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
2913 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2914 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
2916 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
2917 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2918 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
2920 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
2921 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2922 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2924 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
2925 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2926 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2928 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
2929 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2930 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2932 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
2933 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2934 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
2936 hr
= IMFRateSupport_IsRateSupported(rate_support
, TRUE
, 1.0f
, &rate
);
2937 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2938 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
2940 IMFRateSupport_Release(rate_support
);
2943 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
2944 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
2945 ok(flags
& MEDIASINK_FIXED_STREAMS
, "Unexpected flags %#lx.\n", flags
);
2947 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
2948 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
2949 ok(count
== 1, "Unexpected stream count %lu.\n", count
);
2951 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
2952 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
2954 check_interface(stream
, &IID_IMFMediaEventGenerator
, TRUE
);
2955 check_interface(stream
, &IID_IMFMediaTypeHandler
, TRUE
);
2957 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
2958 ok(hr
== S_OK
, "Failed to get stream id, hr %#lx.\n", hr
);
2959 ok(id
== 0, "Unexpected id %#lx.\n", id
);
2961 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
2962 ok(hr
== S_OK
, "Failed to get media sink, hr %lx.\n", hr
);
2963 ok(sink2
== sink
, "Unexpected sink.\n");
2964 IMFMediaSink_Release(sink2
);
2966 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 1, &stream2
);
2967 ok(hr
== MF_E_INVALIDINDEX
, "Unexpected hr %#lx.\n", hr
);
2969 hr
= IMFMediaSink_GetStreamSinkById(sink
, 1, &stream2
);
2970 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
2972 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
2973 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
2975 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
2976 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
2978 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
2979 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
2981 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
2983 /* Event generator. */
2984 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFMediaEventGenerator
, (void **)&eg
);
2985 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
2987 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
2988 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
2990 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&unk
);
2991 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#lx.\n", hr
);
2993 hr
= IMFStreamSink_QueryInterface(stream
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
2994 ok(hr
== S_OK
, "Failed to get handler interface, hr %#lx.\n", hr
);
2996 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
2997 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
2998 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
2999 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3000 ok(count
== 0, "Unexpected count %lu.\n", count
);
3001 ok(handler
== handler2
, "Unexpected handler.\n");
3003 IMFMediaTypeHandler_Release(handler
);
3004 IMFMediaTypeHandler_Release(handler2
);
3007 hr
= MFCreatePresentationClock(&clock
);
3008 ok(hr
== S_OK
, "Failed to create clock object, hr %#lx.\n", hr
);
3010 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
3011 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3013 hr
= IMFMediaSink_GetPresentationClock(sink
, &clock2
);
3014 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
3016 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
3017 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3019 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
3020 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3022 hr
= MFCreateSystemTimeSource(&time_source
);
3023 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
3025 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
3026 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
3027 IMFPresentationTimeSource_Release(time_source
);
3029 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3030 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3032 hr
= IMFActivate_ShutdownObject(activate
);
3033 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3035 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3036 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3038 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3039 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3041 /* On Win8+ this initialization happens automatically. */
3042 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3043 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3045 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
3046 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3048 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3049 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3050 ok(count
== 0, "Unexpected count %lu.\n", count
);
3052 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3053 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
3054 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid
));
3056 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
3057 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3058 ok(media_type2
== media_type
, "Unexpected media type.\n");
3059 IMFMediaType_Release(media_type2
);
3061 hr
= MFCreateMediaType(&media_type2
);
3062 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3064 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3065 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3067 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3068 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3070 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3071 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3073 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_Float
);
3074 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3076 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3077 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3079 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3080 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3082 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3083 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3085 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3086 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3087 IMFMediaType_Release(media_type
);
3089 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3090 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3092 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3093 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3094 ok(media_type2
== media_type
, "Unexpected media type.\n");
3095 IMFMediaType_Release(media_type
);
3097 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3098 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3100 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, NULL
);
3101 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3103 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3104 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3106 hr
= MFCreateMediaType(&media_type
);
3107 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3109 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3110 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3112 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
3113 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3115 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3116 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3118 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3119 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3121 media_type3
= (void *)0xdeadbeef;
3122 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3123 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3124 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3126 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_FIXED_SIZE_SAMPLES
, 1);
3127 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3129 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_SAMPLE_SIZE
, 1024);
3130 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3132 media_type3
= (void *)0xdeadbeef;
3133 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3134 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3135 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3137 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3138 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3140 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3141 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3143 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3144 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3146 EXPECT_REF(clock
, 3);
3147 hr
= IMFMediaSink_Shutdown(sink
);
3148 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3149 EXPECT_REF(clock
, 1);
3151 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3152 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3154 hr
= IMFMediaSink_Shutdown(sink
);
3155 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3157 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3158 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3160 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3161 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3163 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3164 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3166 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream2
);
3167 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3169 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3170 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3172 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3173 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3176 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3177 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3178 ok(id
== 1, "Unexpected id %lu.\n", id
);
3180 media_type3
= (void *)0xdeadbeef;
3181 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3182 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3183 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3185 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3186 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3188 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3189 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3191 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3192 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
3194 IMFMediaType_Release(media_type2
);
3195 IMFMediaType_Release(media_type
);
3197 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3198 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3200 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3201 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3203 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
3204 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3206 hr
= IMFMediaTypeHandler_GetMajorType(handler
, NULL
);
3207 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3209 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3210 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3212 IMFMediaTypeHandler_Release(handler
);
3214 handler
= (void *)0xdeadbeef;
3215 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3216 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3217 ok(handler
== (void *)0xdeadbeef, "Unexpected pointer.\n");
3219 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, NULL
);
3220 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3222 IMFMediaEventGenerator_Release(eg
);
3223 IMFMediaSink_Release(sink
);
3224 IMFStreamSink_Release(stream
);
3226 refcount
= IMFActivate_Release(activate
);
3227 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
3229 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
3230 hr
= MFCreateMediaType(&media_type
);
3231 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3233 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3234 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3235 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3236 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3238 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3239 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3241 hr
= IMFActivate_SetUINT32(activate
, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
, 1);
3242 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3244 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3245 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3247 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3248 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3249 ok(flags
& MEDIASINK_RATELESS
, "Unexpected flags %#lx.\n", flags
);
3251 hr
= IMFActivate_ShutdownObject(activate
);
3252 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3254 hr
= IMFMediaSink_Shutdown(sink
);
3255 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3257 IMFMediaSink_Release(sink
);
3260 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3261 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3263 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3264 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3265 IMFMediaSink_Release(sink
);
3267 hr
= IMFActivate_ShutdownObject(activate
);
3268 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3270 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3271 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3273 hr
= IMFActivate_GetCount(activate
, &attr_count
);
3274 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3276 hr
= IMFActivate_DetachObject(activate
);
3277 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3279 IMFActivate_Release(activate
);
3281 IMFMediaType_Release(media_type
);
3282 IMFPresentationClock_Release(clock
);
3285 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3288 static void test_sample_grabber_is_mediatype_supported(void)
3290 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
3291 IMFMediaTypeHandler
*handler
;
3292 IMFActivate
*activate
;
3293 IMFStreamSink
*stream
;
3299 /* IsMediaTypeSupported checks are done against the creation type, and check format data */
3300 hr
= MFCreateMediaType(&media_type
);
3301 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3303 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3304 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3305 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3306 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3307 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3308 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3310 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3311 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3313 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3314 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3316 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3317 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
3318 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3319 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3320 IMFStreamSink_Release(stream
);
3322 IMFMediaSink_Release(sink
);
3324 /* On Win8+ this initialization happens automatically. */
3325 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3326 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3328 hr
= MFCreateMediaType(&media_type2
);
3329 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3331 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3332 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3333 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3334 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3335 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3336 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3338 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3339 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3341 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3342 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Failed to set media type, hr %#lx.\n", hr
);
3344 /* Make it match grabber type sample rate. */
3345 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3346 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3348 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3349 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3351 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3352 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3353 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type3
);
3354 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3355 ok(media_type3
== media_type2
, "Unexpected media type instance.\n");
3356 IMFMediaType_Release(media_type3
);
3358 /* Change original type. */
3359 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3360 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3362 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3363 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3365 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3366 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3368 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3369 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3371 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3372 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3373 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3375 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3376 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3378 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3379 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3380 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3382 IMFMediaType_Release(media_type2
);
3383 IMFMediaType_Release(media_type
);
3385 IMFMediaTypeHandler_Release(handler
);
3387 refcount
= IMFActivate_Release(activate
);
3388 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
3391 static BOOL
is_supported_video_type(const GUID
*guid
)
3393 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
3394 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
3395 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
3396 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
3397 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
3398 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
3399 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
3400 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
3401 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
3402 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
3403 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
3404 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
3405 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
3406 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
3407 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
3408 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
3409 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
3410 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
3411 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
3412 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
3413 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
3414 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
3415 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
3416 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
3417 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
3418 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
3419 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
3420 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
3421 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
3422 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
3423 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
3426 static void test_video_processor(void)
3428 DWORD input_count
, output_count
, input_id
, output_id
, flags
;
3429 DWORD input_min
, input_max
, output_min
, output_max
, i
;
3430 IMFAttributes
*attributes
, *attributes2
;
3431 IMFMediaType
*media_type
, *media_type2
;
3432 MFT_OUTPUT_DATA_BUFFER output_buffer
;
3433 MFT_OUTPUT_STREAM_INFO output_info
;
3434 MFT_INPUT_STREAM_INFO input_info
;
3435 IMFSample
*sample
, *sample2
;
3436 IMFTransform
*transform
;
3437 IMFMediaBuffer
*buffer
;
3438 IMFMediaEvent
*event
;
3444 hr
= CoInitialize(NULL
);
3445 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3447 hr
= CoCreateInstance(&CLSID_VideoProcessorMFT
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
,
3448 (void **)&transform
);
3451 skip("Failed to create Video Processor instance, skipping tests.\n");
3456 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
3458 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
3459 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
3460 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
3462 /* Transform global attributes. */
3463 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3464 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3466 hr
= IMFAttributes_GetCount(attributes
, &count
);
3467 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3469 ok(!!count
, "Unexpected attribute count %u.\n", count
);
3472 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D11_AWARE
, &value
);
3474 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3475 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
3477 hr
= IMFTransform_GetAttributes(transform
, &attributes2
);
3478 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3479 ok(attributes
== attributes2
, "Unexpected instance.\n");
3480 IMFAttributes_Release(attributes
);
3481 IMFAttributes_Release(attributes2
);
3483 hr
= IMFTransform_GetStreamLimits(transform
, &input_min
, &input_max
, &output_min
, &output_max
);
3484 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
3485 ok(input_min
== input_max
&& input_min
== 1 && output_min
== output_max
&& output_min
== 1,
3486 "Unexpected stream limits.\n");
3488 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
3489 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
3490 ok(input_count
== 1 && output_count
== 1, "Unexpected stream count %lu, %lu.\n", input_count
, output_count
);
3492 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
3493 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3496 hr
= IMFTransform_AddInputStreams(transform
, 1, &input_id
);
3497 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3499 hr
= IMFTransform_DeleteInputStream(transform
, 0);
3500 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3502 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3504 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3506 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
3507 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3509 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
3511 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3513 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
3514 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3515 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes2
);
3516 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3517 ok(attributes
== attributes2
, "Unexpected instance.\n");
3518 IMFAttributes_Release(attributes
);
3519 IMFAttributes_Release(attributes2
);
3521 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3523 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3525 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
3527 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3529 hr
= IMFTransform_GetInputCurrentType(transform
, 1, &media_type
);
3531 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3533 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
3535 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3537 hr
= IMFTransform_GetOutputCurrentType(transform
, 1, &media_type
);
3539 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3541 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
3543 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3545 memset(&input_info
, 0xcc, sizeof(input_info
));
3546 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3548 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3549 ok(input_info
.dwFlags
== 0, "Unexpected flag %#lx.\n", input_info
.dwFlags
);
3550 ok(input_info
.cbSize
== 0, "Unexpected size %lu.\n", input_info
.cbSize
);
3551 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
3552 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
3554 hr
= MFCreateMediaEvent(MEUnknown
, &GUID_NULL
, S_OK
, NULL
, &event
);
3555 ok(hr
== S_OK
, "Failed to create event object, hr %#lx.\n", hr
);
3556 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
3557 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3558 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
3559 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3560 IMFMediaEvent_Release(event
);
3562 /* Configure stream types. */
3565 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
3568 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3572 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
3573 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
3574 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3575 IMFMediaType_Release(media_type2
);
3577 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
3578 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
3579 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
3581 hr
= IMFMediaType_GetCount(media_type
, &count
);
3582 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
3583 ok(count
== 2, "Unexpected count %u.\n", count
);
3585 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
3586 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
3587 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
3589 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3590 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
3592 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3593 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
3595 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
3596 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3598 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
3599 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
3600 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
3601 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
3603 IMFMediaType_Release(media_type
);
3607 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3608 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3610 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3611 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
3613 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3614 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
3616 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
3617 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3618 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3619 IMFMediaType_Release(media_type2
);
3621 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3622 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
3623 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
3625 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3626 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3627 ok(input_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
3628 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
3629 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
3631 IMFMediaType_Release(media_type
);
3635 hr
= MFCreateMediaType(&media_type
);
3636 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3638 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3639 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3641 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
3642 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3644 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3645 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3647 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3649 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
3651 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
3652 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3654 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3656 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
3658 memset(&output_info
, 0, sizeof(output_info
));
3659 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
3661 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3662 ok(output_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
3664 ok(output_info
.cbSize
> 0, "Unexpected size %lu.\n", output_info
.cbSize
);
3665 ok(output_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
3667 hr
= MFCreateSample(&sample
);
3668 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
3670 hr
= MFCreateSample(&sample2
);
3671 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
3673 memset(&output_buffer
, 0, sizeof(output_buffer
));
3674 output_buffer
.pSample
= sample
;
3676 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3678 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
3679 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3680 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3682 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3684 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
3686 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3688 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
3690 memset(&output_buffer
, 0, sizeof(output_buffer
));
3691 output_buffer
.pSample
= sample
;
3693 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3695 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
3696 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3697 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3699 hr
= IMFSample_SetSampleTime(sample2
, 0);
3700 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
3701 memset(&output_buffer
, 0, sizeof(output_buffer
));
3702 output_buffer
.pSample
= sample
;
3704 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3706 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3707 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3708 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3710 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
3711 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
3713 hr
= IMFSample_AddBuffer(sample2
, buffer
);
3714 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
3716 hr
= IMFSample_AddBuffer(sample
, buffer
);
3717 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
3719 memset(&output_buffer
, 0, sizeof(output_buffer
));
3720 output_buffer
.pSample
= sample
;
3722 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3724 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
3725 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3726 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3730 memset(&output_buffer
, 0, sizeof(output_buffer
));
3731 output_buffer
.pSample
= sample
;
3733 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3734 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
3735 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3736 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3739 IMFSample_Release(sample2
);
3740 IMFSample_Release(sample
);
3741 IMFMediaBuffer_Release(buffer
);
3743 IMFMediaType_Release(media_type
);
3745 IMFTransform_Release(transform
);
3751 static void test_quality_manager(void)
3753 IMFPresentationClock
*clock
;
3754 IMFQualityManager
*manager
;
3755 IMFTopology
*topology
;
3758 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3759 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
3761 hr
= MFCreatePresentationClock(&clock
);
3762 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
3764 hr
= MFCreateStandardQualityManager(&manager
);
3765 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3767 check_interface(manager
, &IID_IMFQualityManager
, TRUE
);
3768 check_interface(manager
, &IID_IMFClockStateSink
, TRUE
);
3770 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3771 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3773 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3774 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3776 /* Set clock, then shutdown. */
3777 EXPECT_REF(clock
, 1);
3778 EXPECT_REF(manager
, 1);
3779 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3780 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3781 EXPECT_REF(clock
, 2);
3782 EXPECT_REF(manager
, 2);
3784 hr
= IMFQualityManager_Shutdown(manager
);
3785 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3786 EXPECT_REF(clock
, 1);
3788 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3789 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3791 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3792 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3794 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3795 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3797 hr
= IMFQualityManager_Shutdown(manager
);
3798 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3800 IMFQualityManager_Release(manager
);
3802 /* Set clock, then release without shutting down. */
3803 hr
= MFCreateStandardQualityManager(&manager
);
3804 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3806 EXPECT_REF(clock
, 1);
3807 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3808 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3809 EXPECT_REF(clock
, 2);
3811 IMFQualityManager_Release(manager
);
3812 EXPECT_REF(clock
, 2);
3814 IMFPresentationClock_Release(clock
);
3817 hr
= MFCreateStandardQualityManager(&manager
);
3818 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3820 hr
= MFCreateTopology(&topology
);
3821 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3823 EXPECT_REF(topology
, 1);
3824 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3825 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3826 EXPECT_REF(topology
, 2);
3828 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3829 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3830 EXPECT_REF(topology
, 1);
3832 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3833 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3835 EXPECT_REF(topology
, 2);
3836 hr
= IMFQualityManager_Shutdown(manager
);
3837 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3838 EXPECT_REF(topology
, 1);
3840 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3841 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3843 IMFQualityManager_Release(manager
);
3845 hr
= MFCreateStandardQualityManager(&manager
);
3846 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3848 EXPECT_REF(topology
, 1);
3849 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
3850 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3851 EXPECT_REF(topology
, 2);
3853 IMFQualityManager_Release(manager
);
3854 EXPECT_REF(topology
, 1);
3856 IMFTopology_Release(topology
);
3859 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
3862 static void check_sar_rate_support(IMFMediaSink
*sink
)
3864 IMFRateSupport
*rate_support
;
3865 IMFMediaTypeHandler
*handler
;
3866 IMFStreamSink
*stream_sink
;
3867 IMFMediaType
*media_type
;
3871 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rate_support
);
3873 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3874 if (FAILED(hr
)) return;
3876 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
3877 if (hr
== MF_E_SHUTDOWN
)
3879 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
3880 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3882 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3883 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3885 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3886 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3888 IMFRateSupport_Release(rate_support
);
3891 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3893 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
3894 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3896 IMFStreamSink_Release(stream_sink
);
3898 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
3899 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3901 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
3902 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3904 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3907 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3908 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3910 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3911 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3913 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3914 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3916 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3917 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3919 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3920 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3922 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3923 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3925 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3926 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3928 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3929 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3931 IMFMediaType_Release(media_type
);
3935 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3936 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3938 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3939 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3941 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3942 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3944 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3945 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3947 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3948 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3950 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3951 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3953 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3954 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3956 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3957 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
3960 IMFMediaTypeHandler_Release(handler
);
3961 IMFRateSupport_Release(rate_support
);
3964 static void test_sar(void)
3966 IMFPresentationClock
*present_clock
, *present_clock2
;
3967 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
3968 IMFClockStateSink
*state_sink
, *state_sink2
;
3969 IMFMediaTypeHandler
*handler
, *handler2
;
3970 IMFPresentationTimeSource
*time_source
;
3971 IMFSimpleAudioVolume
*simple_volume
;
3972 IMFAudioStreamVolume
*stream_volume
;
3973 IMFMediaSink
*sink
, *sink2
;
3974 IMFStreamSink
*stream_sink
;
3975 IMFAttributes
*attributes
;
3976 DWORD i
, id
, flags
, count
;
3977 IMFActivate
*activate
;
3978 UINT32 channel_count
;
3979 MFCLOCK_STATE state
;
3987 hr
= CoInitialize(NULL
);
3988 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3990 hr
= MFCreateAudioRenderer(NULL
, &sink
);
3991 if (hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
)
3993 skip("No audio playback device available.\n");
3997 ok(hr
== S_OK
, "Failed to create renderer, hr %#lx.\n", hr
);
3999 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4000 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4002 hr
= MFCreatePresentationClock(&present_clock
);
4003 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
4005 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&time_source
);
4007 ok(hr
== S_OK
, "Failed to get time source interface, hr %#lx.\n", hr
);
4011 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink2
);
4012 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4013 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4014 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4015 ok(state_sink
== state_sink2
, "Unexpected clock sink.\n");
4016 IMFClockStateSink_Release(state_sink2
);
4017 IMFClockStateSink_Release(state_sink
);
4019 hr
= IMFPresentationTimeSource_GetUnderlyingClock(time_source
, &clock
);
4020 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
4022 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &flags
);
4023 ok(hr
== S_OK
, "Failed to get flags, hr %#lx.\n", hr
);
4024 ok(flags
== MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
, "Unexpected flags %#lx.\n", flags
);
4026 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
4027 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
4028 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
4030 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4031 ok(hr
== S_OK
, "Failed to get state sink, hr %#lx.\n", hr
);
4033 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4034 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4036 IMFClockStateSink_Release(state_sink
);
4038 IMFPresentationTimeSource_Release(time_source
);
4040 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4041 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4043 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4044 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4046 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4047 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4049 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4050 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4051 ok(count
== 1, "Unexpected count %lu.\n", count
);
4053 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4054 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4055 ok(flags
== (MEDIASINK_FIXED_STREAMS
| MEDIASINK_CAN_PREROLL
), "Unexpected flags %#lx.\n", flags
);
4057 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4058 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4059 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4060 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4061 todo_wine
check_interface(sink
, &IID_IMFPresentationTimeSource
, TRUE
);
4062 todo_wine
check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4063 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, FALSE
);
4064 check_service_interface(sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, TRUE
);
4065 check_service_interface(sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, TRUE
);
4068 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4069 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4071 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4072 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4074 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4075 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4077 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4078 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4080 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4081 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4083 IMFClockStateSink_Release(state_sink
);
4085 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4086 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4088 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4090 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
4092 hr
= MFCreateSystemTimeSource(&time_source
);
4093 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
4095 hr
= IMFPresentationClock_SetTimeSource(present_clock
, time_source
);
4096 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
4097 IMFPresentationTimeSource_Release(time_source
);
4099 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4100 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4102 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4103 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4105 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4106 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4107 ok(present_clock
== present_clock2
, "Unexpected instance.\n");
4108 IMFPresentationClock_Release(present_clock2
);
4111 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
4112 ok(hr
== S_OK
, "Failed to get a stream, hr %#lx.\n", hr
);
4114 check_interface(stream_sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4115 check_interface(stream_sink
, &IID_IMFMediaTypeHandler
, TRUE
);
4116 todo_wine
check_interface(stream_sink
, &IID_IMFGetService
, TRUE
);
4118 hr
= IMFStreamSink_GetIdentifier(stream_sink
, &id
);
4119 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4120 ok(!id
, "Unexpected id.\n");
4122 hr
= IMFStreamSink_GetMediaSink(stream_sink
, &sink2
);
4123 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4124 ok(sink
== sink2
, "Unexpected object.\n");
4125 IMFMediaSink_Release(sink2
);
4127 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
4128 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4130 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
4131 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4132 ok(handler2
== handler
, "Unexpected instance.\n");
4133 IMFMediaTypeHandler_Release(handler2
);
4135 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4136 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4137 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4140 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
4141 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
4142 ok(!!count
, "Unexpected type count %lu.\n", count
);
4144 /* A number of same major/subtype entries are returned, with different degrees of finer format
4145 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
4147 for (i
= 0, found
= -1; i
< count
; ++i
)
4149 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, i
, &mediatype
);
4150 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4152 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
)))
4154 IMFMediaType_Release(mediatype
);
4156 if (found
!= -1) break;
4158 ok(found
!= -1, "Haven't found a supported type.\n");
4160 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4161 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4163 hr
= MFCreateMediaType(&mediatype
);
4164 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4166 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
4167 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4168 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4170 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4171 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4172 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4173 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4175 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
4176 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4177 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4178 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4180 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
4181 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4183 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype2
);
4184 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4186 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype3
);
4187 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4188 ok(mediatype2
== mediatype3
, "Unexpected instance.\n");
4189 IMFMediaType_Release(mediatype3
);
4191 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype2
, NULL
);
4192 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4194 IMFMediaType_Release(mediatype
);
4196 check_sar_rate_support(sink
);
4198 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype2
);
4199 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4201 check_sar_rate_support(sink
);
4203 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4204 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4205 ok(mediatype
== mediatype2
, "Unexpected instance.\n");
4206 IMFMediaType_Release(mediatype
);
4208 IMFMediaType_Release(mediatype2
);
4210 /* Reset back to uninitialized state. */
4211 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
4212 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4214 IMFMediaTypeHandler_Release(handler
);
4216 /* State change with initialized stream. */
4217 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4218 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4220 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4221 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4223 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4224 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4226 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4227 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4229 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4230 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4232 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4233 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4235 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4236 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4238 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4239 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4241 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4242 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4244 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4245 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4247 IMFClockStateSink_Release(state_sink
);
4249 IMFStreamSink_Release(stream_sink
);
4251 /* Volume control */
4252 hr
= MFGetService((IUnknown
*)sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, (void **)&simple_volume
);
4253 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4255 hr
= IMFSimpleAudioVolume_GetMute(simple_volume
, &mute
);
4256 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4258 IMFSimpleAudioVolume_Release(simple_volume
);
4260 hr
= MFGetService((IUnknown
*)sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, (void **)&stream_volume
);
4261 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4263 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, &channel_count
);
4264 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4266 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, NULL
);
4267 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4269 IMFAudioStreamVolume_Release(stream_volume
);
4271 hr
= MFGetService((IUnknown
*)sink
, &MR_AUDIO_POLICY_SERVICE
, &IID_IMFAudioPolicy
, (void **)&unk
);
4272 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4273 IUnknown_Release(unk
);
4276 EXPECT_REF(present_clock
, 2);
4277 hr
= IMFMediaSink_Shutdown(sink
);
4278 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4279 EXPECT_REF(present_clock
, 1);
4281 hr
= IMFMediaSink_Shutdown(sink
);
4282 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4284 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4285 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4287 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4288 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4290 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4291 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4293 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4294 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4296 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4297 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4299 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4300 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4302 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4303 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4305 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4306 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4308 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4309 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4311 check_sar_rate_support(sink
);
4313 IMFMediaSink_Release(sink
);
4316 hr
= MFCreateAudioRendererActivate(&activate
);
4317 ok(hr
== S_OK
, "Failed to create activation object, hr %#lx.\n", hr
);
4319 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4320 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4322 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4323 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4324 ok(sink
== sink2
, "Unexpected instance.\n");
4325 IMFMediaSink_Release(sink2
);
4327 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4328 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
4330 hr
= IMFActivate_ShutdownObject(activate
);
4331 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4333 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4334 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4336 IMFMediaSink_Release(sink
);
4338 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4339 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4341 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4343 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4345 IMFMediaSink_Release(sink
);
4347 hr
= IMFActivate_DetachObject(activate
);
4348 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4350 IMFActivate_Release(activate
);
4352 IMFPresentationClock_Release(present_clock
);
4355 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4357 /* SAR attributes */
4358 hr
= MFCreateAttributes(&attributes
, 0);
4359 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
4362 hr
= IMFAttributes_SetUINT32(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
, eMultimedia
);
4363 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4365 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4366 ok(hr
== S_OK
, "Failed to create a sink, hr %#lx.\n", hr
);
4367 IMFMediaSink_Release(sink
);
4369 /* Invalid endpoint. */
4370 hr
= IMFAttributes_SetString(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
, L
"endpoint");
4371 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4373 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4374 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4376 hr
= IMFAttributes_DeleteItem(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
);
4377 ok(hr
== S_OK
, "Failed to remove attribute, hr %#lx.\n", hr
);
4379 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4380 ok(hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
, "Failed to create a sink, hr %#lx.\n", hr
);
4382 IMFAttributes_Release(attributes
);
4387 static void test_evr(void)
4389 static const float supported_rates
[] =
4391 0.0f
, 1.0f
, -20.0f
, 20.0f
, 1000.0f
, -1000.0f
,
4393 IMFVideoSampleAllocatorCallback
*allocator_callback
;
4394 IMFStreamSink
*stream_sink
, *stream_sink2
;
4395 IMFVideoDisplayControl
*display_control
;
4396 IMFMediaType
*media_type
, *media_type2
;
4397 IMFPresentationTimeSource
*time_source
;
4398 IMFVideoSampleAllocator
*allocator
;
4399 IMFMediaTypeHandler
*type_handler
;
4400 IMFVideoRenderer
*video_renderer
;
4401 IMFPresentationClock
*clock
;
4402 IMFMediaSink
*sink
, *sink2
;
4403 IMFAttributes
*attributes
;
4404 UINT32 attr_count
, value
;
4405 IMFActivate
*activate
;
4406 HWND window
, window2
;
4418 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4419 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4421 hr
= MFCreateVideoRenderer(&IID_IMFVideoRenderer
, (void **)&video_renderer
);
4422 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4424 hr
= IMFVideoRenderer_InitializeRenderer(video_renderer
, NULL
, NULL
);
4425 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4427 IMFVideoRenderer_Release(video_renderer
);
4429 hr
= MFCreateVideoRendererActivate(NULL
, NULL
);
4430 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4433 window
= create_window();
4434 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4435 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4437 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4438 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4439 ok(UlongToHandle(window3
) == window
, "Unexpected value.\n");
4441 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4442 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4444 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4445 check_interface(sink
, &IID_IMFVideoRenderer
, TRUE
);
4446 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4447 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4448 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4449 check_interface(sink
, &IID_IMFQualityAdvise
, TRUE
);
4450 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
4451 check_interface(sink
, &IID_IMFRateControl
, FALSE
);
4452 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
4453 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
4454 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
4455 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
4456 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
4457 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
4458 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, FALSE
);
4459 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
4460 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4462 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
,
4463 (void **)&display_control
);
4464 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4467 hr
= IMFVideoDisplayControl_GetVideoWindow(display_control
, &window2
);
4468 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4469 ok(window2
== window
, "Unexpected window %p.\n", window2
);
4471 IMFVideoDisplayControl_Release(display_control
);
4472 IMFMediaSink_Release(sink
);
4473 IMFActivate_Release(activate
);
4474 DestroyWindow(window
);
4476 hr
= MFCreateVideoRendererActivate(NULL
, &activate
);
4477 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4479 hr
= IMFActivate_GetCount(activate
, &attr_count
);
4480 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
4481 ok(attr_count
== 1, "Unexpected count %u.\n", attr_count
);
4483 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4484 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4485 ok(!window3
, "Unexpected value.\n");
4487 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4488 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4490 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFAttributes
, (void **)&attributes
);
4491 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4492 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFMediaSink
, (void **)&unk
);
4493 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4494 IUnknown_Release(unk
);
4495 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4496 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4497 ok(!!attr_count
, "Unexpected count %u.\n", attr_count
);
4498 /* Rendering preferences are not immediately propagated to the presenter. */
4499 hr
= IMFAttributes_SetUINT32(attributes
, &EVRConfig_ForceBob
, 1);
4500 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4501 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, (void **)&display_control
);
4502 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4503 hr
= IMFVideoDisplayControl_GetRenderingPrefs(display_control
, &flags
);
4504 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4505 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
4506 IMFVideoDisplayControl_Release(display_control
);
4507 IMFAttributes_Release(attributes
);
4509 /* Primary stream type handler. */
4510 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4511 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4513 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFAttributes
, (void **)&attributes
);
4514 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4515 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4516 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4517 ok(attr_count
== 2, "Unexpected count %u.\n", attr_count
);
4519 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, &value
);
4520 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4521 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4523 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D_AWARE
, &value
);
4524 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4525 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4527 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFStreamSink
, (void **)&unk
);
4528 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4529 IUnknown_Release(unk
);
4530 IMFAttributes_Release(attributes
);
4532 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
4533 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4535 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, NULL
);
4536 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4538 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, &guid
);
4539 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4540 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4542 /* Supported types are not advertised. */
4543 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, NULL
);
4544 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4547 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, &count
);
4548 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4549 ok(!count
, "Unexpected count %lu.\n", count
);
4551 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, NULL
);
4552 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4554 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, &media_type
);
4555 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4557 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, NULL
);
4558 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4560 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type
);
4561 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4563 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, NULL
);
4564 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4566 hr
= MFCreateMediaType(&media_type
);
4567 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4569 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4570 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4572 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4573 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4575 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
4576 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4578 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, NULL
, NULL
);
4579 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4581 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4582 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4584 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
4585 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4587 media_type2
= (void *)0x1;
4588 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4589 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4590 ok(!media_type2
, "Unexpected media type %p.\n", media_type2
);
4592 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
4593 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4595 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type2
);
4596 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4597 hr
= IMFMediaType_QueryInterface(media_type2
, &IID_IMFVideoMediaType
, (void **)&unk
);
4598 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4599 IUnknown_Release(unk
);
4600 IMFMediaType_Release(media_type2
);
4602 IMFMediaType_Release(media_type
);
4604 IMFMediaTypeHandler_Release(type_handler
);
4606 /* Stream uses an allocator. */
4607 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, TRUE
);
4608 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
4610 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
4611 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
4612 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
4613 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
4614 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
4615 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
4616 check_service_interface(stream_sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4618 hr
= MFGetService((IUnknown
*)stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4619 (void **)&allocator
);
4620 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4622 hr
= IMFVideoSampleAllocator_QueryInterface(allocator
, &IID_IMFVideoSampleAllocatorCallback
, (void **)&allocator_callback
);
4623 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4626 hr
= IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback
, &sample_count
);
4627 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4628 ok(!sample_count
, "Unexpected sample count %ld.\n", sample_count
);
4630 hr
= IMFVideoSampleAllocator_AllocateSample(allocator
, &sample
);
4631 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4633 IMFVideoSampleAllocatorCallback_Release(allocator_callback
);
4634 IMFVideoSampleAllocator_Release(allocator
);
4636 /* Same test for a substream. */
4637 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream_sink2
);
4638 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4642 hr
= MFGetService((IUnknown
*)stream_sink2
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4643 (void **)&allocator
);
4644 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4645 IMFVideoSampleAllocator_Release(allocator
);
4647 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
4648 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4650 IMFStreamSink_Release(stream_sink2
);
4653 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4654 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4655 ok(flags
== (MEDIASINK_CAN_PREROLL
| MEDIASINK_CLOCK_REQUIRED
), "Unexpected flags %#lx.\n", flags
);
4657 hr
= IMFActivate_ShutdownObject(activate
);
4658 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4660 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4661 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4663 /* Activate again. */
4664 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4665 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4667 ok(sink
== sink2
, "Unexpected instance.\n");
4668 IMFMediaSink_Release(sink2
);
4670 hr
= IMFActivate_DetachObject(activate
);
4671 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4673 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4674 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4676 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4677 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4679 hr
= IMFActivate_ShutdownObject(activate
);
4680 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4682 IMFMediaSink_Release(sink2
);
4683 IMFMediaSink_Release(sink
);
4685 IMFActivate_Release(activate
);
4688 window
= create_window();
4690 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4691 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4693 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4694 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4696 hr
= MFCreateSystemTimeSource(&time_source
);
4697 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4699 hr
= MFCreatePresentationClock(&clock
);
4700 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4702 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
4703 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4704 IMFPresentationTimeSource_Release(time_source
);
4706 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
4707 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4709 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rs
);
4710 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4713 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4714 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4715 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4718 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
4719 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4720 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4723 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4724 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4725 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4728 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4729 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4730 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4732 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4733 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4735 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
4736 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4738 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4739 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4741 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4742 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4744 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4745 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4747 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
4749 rate
= supported_rates
[i
] + 1.0f
;
4750 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
4751 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4752 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4754 rate
= supported_rates
[i
] + 1.0f
;
4755 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
4756 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4757 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4759 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
4760 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4762 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
4763 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4766 /* Configuring stream type make rate support work. */
4767 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4768 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4769 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
4770 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4771 hr
= MFCreateMediaType(&media_type
);
4772 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4773 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4774 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4775 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4776 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4777 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)64 << 32 | 64);
4778 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4779 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
4780 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4781 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
4782 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4785 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4786 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4787 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4790 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4791 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4792 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4795 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4796 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4797 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
4800 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4801 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4802 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
4804 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4805 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4807 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4808 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4810 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
4812 rate
= supported_rates
[i
] + 1.0f
;
4813 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
4814 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4815 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4817 rate
= supported_rates
[i
] + 1.0f
;
4818 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
4819 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4820 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4822 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
4823 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4825 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
4826 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4829 IMFMediaTypeHandler_Release(type_handler
);
4830 IMFMediaType_Release(media_type
);
4831 IMFStreamSink_Release(stream_sink
);
4833 hr
= IMFMediaSink_Shutdown(sink
);
4834 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4836 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4837 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4839 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4840 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4842 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4843 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4845 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4846 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4848 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
4849 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4851 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
4852 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4854 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, 1.0f
, &rate
);
4855 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4857 IMFPresentationClock_Release(clock
);
4859 IMFActivate_Release(activate
);
4860 DestroyWindow(window
);
4863 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4866 static void test_MFCreateSimpleTypeHandler(void)
4868 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
4869 IMFMediaTypeHandler
*handler
;
4874 hr
= MFCreateSimpleTypeHandler(&handler
);
4875 ok(hr
== S_OK
, "Failed to create object, hr %#lx.\n", hr
);
4877 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
4878 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4880 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
4881 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
4884 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
4885 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
4886 ok(count
== 1, "Unexpected count %lu.\n", count
);
4888 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
4889 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4891 media_type
= (void *)0xdeadbeef;
4892 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
4893 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4894 ok(!media_type
, "Unexpected pointer.\n");
4896 hr
= MFCreateMediaType(&media_type
);
4897 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4899 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
4900 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
4902 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
4903 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4905 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type2
);
4906 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4907 ok(media_type2
== media_type
, "Unexpected type.\n");
4908 IMFMediaType_Release(media_type2
);
4910 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
4911 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4913 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
4914 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4916 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type2
);
4917 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4919 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 1, &media_type2
);
4920 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4922 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
4923 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4924 ok(media_type
== media_type2
, "Unexpected pointer.\n");
4925 IMFMediaType_Release(media_type2
);
4927 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4928 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
4930 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4931 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4933 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4934 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4935 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
4937 hr
= MFCreateMediaType(&media_type3
);
4938 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4940 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, NULL
);
4941 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4943 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
4944 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4946 /* Different major types. */
4947 media_type2
= (void *)0xdeadbeef;
4948 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4949 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
4950 ok(!media_type2
, "Unexpected pointer.\n");
4952 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4953 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4955 media_type2
= (void *)0xdeadbeef;
4956 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4957 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4958 ok(!media_type2
, "Unexpected pointer.\n");
4960 /* Handler missing subtype. */
4961 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
4962 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4964 media_type2
= (void *)0xdeadbeef;
4965 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4966 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
4967 ok(!media_type2
, "Unexpected pointer.\n");
4969 /* Different subtypes. */
4970 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
4971 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4973 media_type2
= (void *)0xdeadbeef;
4974 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4975 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
4976 ok(!media_type2
, "Unexpected pointer.\n");
4978 /* Same major/subtype. */
4979 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
4980 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4982 media_type2
= (void *)0xdeadbeef;
4983 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4984 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4985 ok(!media_type2
, "Unexpected pointer.\n");
4987 /* Set one more attribute. */
4988 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)4 << 32 | 4);
4989 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4991 media_type2
= (void *)0xdeadbeef;
4992 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
4993 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4994 ok(!media_type2
, "Unexpected pointer.\n");
4996 IMFMediaType_Release(media_type3
);
4997 IMFMediaType_Release(media_type
);
4999 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
5000 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5002 media_type
= (void *)0xdeadbeef;
5003 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
5004 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5005 ok(!media_type
, "Unexpected pointer.\n");
5007 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5008 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
5010 IMFMediaTypeHandler_Release(handler
);
5013 static void test_MFGetSupportedMimeTypes(void)
5018 hr
= MFGetSupportedMimeTypes(NULL
);
5019 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5021 value
.vt
= VT_EMPTY
;
5022 hr
= MFGetSupportedMimeTypes(&value
);
5023 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5024 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5026 PropVariantClear(&value
);
5029 static void test_MFGetSupportedSchemes(void)
5034 hr
= MFGetSupportedSchemes(NULL
);
5035 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5037 value
.vt
= VT_EMPTY
;
5038 hr
= MFGetSupportedSchemes(&value
);
5039 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5040 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5042 PropVariantClear(&value
);
5045 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
5051 hr
= IMFMediaType_GetMajorType(type
, &major
);
5052 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5054 hr
= IMFMediaType_GetCount(type
, &count
);
5055 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
5056 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5058 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
5061 static void test_sample_copier(void)
5063 IMFAttributes
*attributes
, *attributes2
;
5064 DWORD in_min
, in_max
, out_min
, out_max
;
5065 IMFMediaType
*mediatype
, *mediatype2
;
5066 MFT_OUTPUT_STREAM_INFO output_info
;
5067 IMFSample
*sample
, *client_sample
;
5068 MFT_INPUT_STREAM_INFO input_info
;
5069 DWORD input_count
, output_count
;
5070 MFT_OUTPUT_DATA_BUFFER buffer
;
5071 IMFMediaBuffer
*media_buffer
;
5072 IMFTransform
*copier
;
5073 DWORD flags
, status
;
5074 UINT32 value
, count
;
5077 if (!pMFCreateSampleCopierMFT
)
5079 win_skip("MFCreateSampleCopierMFT() is not available.\n");
5083 hr
= pMFCreateSampleCopierMFT(&copier
);
5084 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5086 hr
= IMFTransform_GetAttributes(copier
, &attributes
);
5087 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5088 hr
= IMFTransform_GetAttributes(copier
, &attributes2
);
5089 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5090 ok(attributes
== attributes2
, "Unexpected instance.\n");
5091 IMFAttributes_Release(attributes2
);
5092 hr
= IMFAttributes_GetCount(attributes
, &count
);
5093 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5094 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5095 hr
= IMFAttributes_GetUINT32(attributes
, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, &value
);
5096 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5097 ok(!!value
, "Unexpected value %u.\n", value
);
5098 IMFAttributes_Release(attributes
);
5100 hr
= IMFTransform_GetInputStreamAttributes(copier
, 0, &attributes
);
5101 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5103 hr
= IMFTransform_GetInputStreamAttributes(copier
, 1, &attributes
);
5104 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5106 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 0, &attributes
);
5107 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5109 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 1, &attributes
);
5110 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5112 hr
= IMFTransform_SetOutputBounds(copier
, 0, 0);
5113 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5115 /* No dynamic streams. */
5116 input_count
= output_count
= 0;
5117 hr
= IMFTransform_GetStreamCount(copier
, &input_count
, &output_count
);
5118 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
5119 ok(input_count
== 1 && output_count
== 1, "Unexpected streams count.\n");
5121 hr
= IMFTransform_GetStreamLimits(copier
, &in_min
, &in_max
, &out_min
, &out_max
);
5122 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
5123 ok(in_min
== in_max
&& in_min
== 1 && out_min
== out_max
&& out_min
== 1, "Unexpected stream limits.\n");
5125 hr
= IMFTransform_GetStreamIDs(copier
, 1, &input_count
, 1, &output_count
);
5126 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5128 hr
= IMFTransform_DeleteInputStream(copier
, 0);
5129 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5131 /* Available types. */
5132 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
5133 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5134 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5135 IMFMediaType_Release(mediatype
);
5137 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
5138 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5139 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5140 IMFMediaType_Release(mediatype
);
5142 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
5143 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5145 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
5146 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5148 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
5149 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5151 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
5152 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5154 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype
);
5155 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5157 hr
= IMFTransform_GetInputCurrentType(copier
, 1, &mediatype
);
5158 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5160 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype
);
5161 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5163 hr
= IMFTransform_GetOutputCurrentType(copier
, 1, &mediatype
);
5164 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5166 hr
= MFCreateSample(&sample
);
5167 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5169 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5170 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5172 hr
= MFCreateMediaType(&mediatype
);
5173 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5175 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5176 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
5178 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5179 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5181 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
5182 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5184 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5185 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5187 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5188 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5189 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5190 ok(!output_info
.cbSize
, "Unexpected size %lu.\n", output_info
.cbSize
);
5191 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5193 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5194 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5196 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5197 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5198 ok(!input_info
.cbSize
, "Unexpected size %lu.\n", input_info
.cbSize
);
5199 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5200 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5202 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5203 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5205 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5206 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5207 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5208 ok(output_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", output_info
.cbSize
);
5209 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5211 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5212 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5213 IMFMediaType_Release(mediatype2
);
5215 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5216 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5218 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5219 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5221 /* Setting input type resets output type. */
5222 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5223 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5224 IMFMediaType_Release(mediatype2
);
5226 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5227 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5229 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5230 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5232 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
5233 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5234 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
5235 IMFMediaType_Release(mediatype2
);
5237 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5238 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5239 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5240 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5241 ok(input_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", input_info
.cbSize
);
5242 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5243 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5245 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
5246 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5247 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
5248 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5249 IMFMediaType_Release(mediatype2
);
5251 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5252 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5253 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
5255 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5256 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5257 IMFMediaType_Release(mediatype2
);
5259 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5260 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5262 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5263 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
5265 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5266 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5267 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5269 /* Pushing samples. */
5270 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5271 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5273 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
5274 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5275 IMFMediaBuffer_Release(media_buffer
);
5277 EXPECT_REF(sample
, 1);
5278 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5279 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5280 EXPECT_REF(sample
, 2);
5282 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5283 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5284 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5286 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5287 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5288 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
5290 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5291 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
5293 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5294 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5296 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5297 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5299 hr
= MFCreateSample(&client_sample
);
5300 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5302 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
5303 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5304 IMFMediaBuffer_Release(media_buffer
);
5307 memset(&buffer
, 0, sizeof(buffer
));
5308 buffer
.pSample
= client_sample
;
5309 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5310 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5311 EXPECT_REF(sample
, 1);
5313 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5314 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
5317 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5318 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5319 EXPECT_REF(sample
, 2);
5321 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
5322 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
5323 EXPECT_REF(sample
, 1);
5325 IMFSample_Release(sample
);
5326 IMFSample_Release(client_sample
);
5328 IMFMediaType_Release(mediatype
);
5329 IMFTransform_Release(copier
);
5332 struct sample_metadata
5339 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
5340 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
5342 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
5343 IMFSample
*input_sample
, *output_sample
;
5344 MFT_OUTPUT_DATA_BUFFER buffer
;
5345 DWORD flags
, status
;
5349 hr
= MFCreateSample(&input_sample
);
5350 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5354 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
5355 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5357 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
5358 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5360 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
5361 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5364 hr
= MFCreateSample(&output_sample
);
5365 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5367 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
5368 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5370 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
5371 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5373 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
5374 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5376 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
5377 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5379 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
5380 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5382 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
5383 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5386 memset(&buffer
, 0, sizeof(buffer
));
5387 buffer
.pSample
= output_sample
;
5388 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5389 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5391 if (!md
) md
= &zero_md
;
5393 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
5394 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5395 ok(md
->flags
== flags
, "Unexpected flags.\n");
5396 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
5397 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5398 ok(md
->time
== time
, "Unexpected time.\n");
5399 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
5400 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5401 ok(md
->duration
== time
, "Unexpected duration.\n");
5403 IMFSample_Release(input_sample
);
5404 IMFSample_Release(output_sample
);
5407 static void test_sample_copier_output_processing(void)
5409 IMFMediaBuffer
*input_buffer
, *output_buffer
;
5410 MFT_OUTPUT_STREAM_INFO output_info
;
5411 struct sample_metadata md
;
5412 IMFMediaType
*mediatype
;
5413 IMFTransform
*copier
;
5418 if (!pMFCreateSampleCopierMFT
)
5421 hr
= pMFCreateSampleCopierMFT(&copier
);
5422 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5424 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
5425 hr
= MFCreateMediaType(&mediatype
);
5426 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5428 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5429 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5431 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5432 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5434 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5435 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5437 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5438 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5440 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5441 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5443 /* Source and destination are linear buffers, destination is twice as large. */
5444 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5445 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5447 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
5448 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5450 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5451 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5452 memset(ptr
, 0xcc, max_length
);
5453 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5454 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5456 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
5457 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5459 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
5460 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5461 memset(ptr
, 0xaa, max_length
);
5462 hr
= IMFMediaBuffer_Unlock(input_buffer
);
5463 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5464 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
5465 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5467 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
5469 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5470 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5471 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
5473 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5474 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5479 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
5481 IMFMediaBuffer_Release(input_buffer
);
5482 IMFMediaBuffer_Release(output_buffer
);
5484 IMFMediaType_Release(mediatype
);
5485 IMFTransform_Release(copier
);
5488 static void test_MFGetTopoNodeCurrentType(void)
5490 IMFMediaType
*media_type
, *media_type2
;
5491 IMFTopologyNode
*node
;
5494 if (!pMFGetTopoNodeCurrentType
)
5496 win_skip("MFGetTopoNodeCurrentType() is unsupported.\n");
5501 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
5502 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
5504 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5505 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5507 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5508 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5510 hr
= MFCreateMediaType(&media_type2
);
5511 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5513 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5514 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5516 /* Input type returned, if set. */
5517 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, media_type2
);
5518 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5520 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5521 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5522 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5523 IMFMediaType_Release(media_type
);
5525 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
5526 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5528 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5529 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5531 /* Set second output. */
5532 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5533 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5535 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5536 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5538 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, NULL
);
5539 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5541 /* Set first output. */
5542 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, media_type2
);
5543 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5545 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5546 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5547 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5548 IMFMediaType_Release(media_type
);
5550 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, NULL
);
5551 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5553 /* Set primary output. */
5554 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5555 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5557 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_PRIMARYOUTPUT
, 1);
5558 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5560 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5561 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5562 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5563 IMFMediaType_Release(media_type
);
5565 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5566 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5567 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5568 IMFMediaType_Release(media_type
);
5570 IMFTopologyNode_Release(node
);
5571 IMFMediaType_Release(media_type2
);
5574 static void init_functions(void)
5576 HMODULE mod
= GetModuleHandleA("mf.dll");
5578 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
5579 X(MFCreateSampleCopierMFT
);
5580 X(MFGetTopoNodeCurrentType
);
5584 static void test_MFRequireProtectedEnvironment(void)
5586 IMFPresentationDescriptor
*pd
;
5587 IMFMediaType
*mediatype
;
5588 IMFStreamDescriptor
*sd
;
5591 hr
= MFCreateMediaType(&mediatype
);
5592 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5594 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
5595 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
5597 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
5598 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
5600 hr
= IMFPresentationDescriptor_SelectStream(pd
, 0);
5601 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5603 hr
= MFRequireProtectedEnvironment(pd
);
5604 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
5606 hr
= IMFStreamDescriptor_SetUINT32(sd
, &MF_SD_PROTECTED
, 1);
5607 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5609 hr
= MFRequireProtectedEnvironment(pd
);
5610 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5612 hr
= IMFPresentationDescriptor_DeselectStream(pd
, 0);
5613 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5615 hr
= MFRequireProtectedEnvironment(pd
);
5616 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5618 IMFMediaType_Release(mediatype
);
5619 IMFStreamDescriptor_Release(sd
);
5620 IMFPresentationDescriptor_Release(pd
);
5623 static BOOL
create_transform(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
5624 MFT_REGISTER_TYPE_INFO
*output_type
, const WCHAR
*expect_name
,
5625 const media_type_desc
*expect_input
, ULONG expect_input_count
,
5626 const media_type_desc
*expect_output
, ULONG expect_output_count
,
5627 IMFTransform
**transform
, GUID
*class_id
)
5629 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
5630 UINT32 input_count
= 0, output_count
= 0, count
= 0, i
;
5631 GUID
*class_ids
= NULL
;
5635 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
5639 win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name
));
5643 ok(hr
== S_OK
, "MFTEnum returned %lx\n", hr
);
5644 ok(count
== 1, "got %u\n", count
);
5645 *class_id
= class_ids
[0];
5646 CoTaskMemFree(class_ids
);
5648 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
5652 win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name
));
5656 ok(hr
== S_OK
, "MFTEnum returned %lx\n", hr
);
5657 ok(!wcscmp(name
, expect_name
), "got name %s\n", debugstr_w(name
));
5658 ok(input_count
== expect_input_count
, "got input_count %u\n", input_count
);
5659 for (i
= 0; i
< input_count
; ++i
)
5661 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect_input
[i
][0].value
.puuid
),
5662 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
5663 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect_input
[i
][1].value
.puuid
),
5664 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
5666 ok(output_count
== expect_output_count
, "got output_count %u\n", output_count
);
5667 for (i
= 0; i
< output_count
; ++i
)
5669 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect_output
[i
][0].value
.puuid
),
5670 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
5671 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect_output
[i
][1].value
.puuid
),
5672 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
5674 CoTaskMemFree(output_types
);
5675 CoTaskMemFree(input_types
);
5676 CoTaskMemFree(name
);
5679 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)transform
);
5683 win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name
));
5690 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
5692 IMFMediaBuffer
*media_buffer
;
5699 hr
= MFCreateSample(&sample
);
5700 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
5701 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
5702 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
5703 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5704 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5705 ok(length
== 0, "got length %lu\n", length
);
5706 if (!data
) memset(buffer
, 0xcd, size
);
5707 else memcpy(buffer
, data
, size
);
5708 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5709 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5710 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
5711 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
5712 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
5713 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
5714 ret
= IMFMediaBuffer_Release(media_buffer
);
5715 ok(ret
== 1, "Release returned %lu\n", ret
);
5720 #define check_sample(a, b, c, d) check_sample_(__LINE__, a, b, c, d)
5721 static void check_sample_(int line
, IMFSample
*sample
, const void *expect_buf
, ULONG expect_len
, HANDLE output_file
)
5723 IMFMediaBuffer
*media_buffer
;
5729 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
5730 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
5731 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5732 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5733 ok_(__FILE__
, line
)(expect_len
== length
, "got length %lu\n", length
);
5734 if (length
&& length
== expect_len
)
5736 ok_(__FILE__
, line
)(!memcmp(expect_buf
, buffer
, expect_len
),
5737 "unexpected buffer data\n");
5739 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
5740 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5741 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5742 ret
= IMFMediaBuffer_Release(media_buffer
);
5743 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
5746 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
5747 static const BYTE wma_decoded_data
[0x4000] = {0};
5748 static const ULONG wma_block_size
= 1487;
5750 static void test_wma_encoder(void)
5752 static const media_type_desc transform_inputs
[] =
5755 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5756 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5759 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5760 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5763 static const media_type_desc transform_outputs
[] =
5766 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5767 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
5770 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5771 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
5774 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5775 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
5779 static const struct attribute_desc input_type_desc
[] =
5781 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5782 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5783 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
5784 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5785 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5786 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
5787 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
5790 const struct attribute_desc output_type_desc
[] =
5792 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5793 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
5794 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5795 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5796 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
5797 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wma_block_size
),
5798 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
5802 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
5803 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
5804 MFT_OUTPUT_STREAM_INFO output_info
;
5805 MFT_INPUT_STREAM_INFO input_info
;
5806 MFT_OUTPUT_DATA_BUFFER output
;
5807 const BYTE
*wma_encoded_data
;
5808 WCHAR output_path
[MAX_PATH
];
5809 ULONG wma_encoded_data_len
;
5810 IMFMediaType
*media_type
;
5811 IMFTransform
*transform
;
5820 hr
= CoInitialize(NULL
);
5821 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5823 if (!create_transform(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, L
"WMAudio Encoder MFT",
5824 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
5825 &transform
, &class_id
))
5828 check_interface(transform
, &IID_IMediaObject
, TRUE
);
5830 hr
= MFCreateMediaType(&media_type
);
5831 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
5832 init_media_type(media_type
, input_type_desc
, -1);
5833 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5834 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5835 init_media_type(media_type
, output_type_desc
, -1);
5836 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
5837 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5838 ret
= IMFMediaType_Release(media_type
);
5839 ok(ret
== 0, "Release returned %lu\n", ret
);
5841 memset(&input_info
, 0xcd, sizeof(input_info
));
5842 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
5843 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
5844 ok(input_info
.hnsMaxLatency
== 19969161, "got hnsMaxLatency %s\n",
5845 wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5846 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
5847 ok(input_info
.cbSize
== 8, "got cbSize %lu\n", input_info
.cbSize
);
5848 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
5849 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
5851 memset(&output_info
, 0xcd, sizeof(output_info
));
5852 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
5853 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
5854 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
5855 ok(output_info
.cbSize
== wma_block_size
, "got cbSize %#lx\n", output_info
.cbSize
);
5856 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
5859 sample
= create_sample(wma_decoded_data
, sizeof(wma_decoded_data
));
5860 while (SUCCEEDED(hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0)))
5862 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5863 i
+= sizeof(wma_decoded_data
);
5865 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5866 ok(i
== 0x204000, "ProcessInput consumed %#lx bytes\n", i
);
5868 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
5869 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
5870 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
5871 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5873 status
= 0xdeadbeef;
5874 sample
= create_sample(NULL
, output_info
.cbSize
);
5875 memset(&output
, 0, sizeof(output
));
5876 output
.pSample
= sample
;
5878 /* check wmadata.bin against current encoder output */
5879 resource
= FindResourceW(NULL
, L
"wmadata.bin", (const WCHAR
*)RT_RCDATA
);
5880 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
5881 wma_encoded_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
5882 wma_encoded_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
5883 ok(wma_encoded_data_len
% wma_block_size
== 0, "got wma encoded length %lu\n", wma_encoded_data_len
);
5885 /* and generate a new one as well in a temporary directory */
5886 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
5887 lstrcatW(output_path
, L
"wmadata.bin");
5888 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
5889 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
5892 while (SUCCEEDED(hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
)))
5894 winetest_push_context("%lu", i
);
5895 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5896 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
5897 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
5898 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|5)) /* win7 */,
5899 "got dwStatus %#lx\n", output
.dwStatus
);
5900 ok(status
== 0, "got status %#lx\n", status
);
5901 ok(wma_encoded_data_len
> i
* wma_block_size
, "got %lu blocks\n", i
);
5902 check_sample(sample
, wma_encoded_data
+ i
* wma_block_size
, wma_block_size
, output_file
);
5903 winetest_pop_context();
5907 trace("created %s\n", debugstr_w(output_path
));
5908 CloseHandle(output_file
);
5910 ret
= IMFSample_Release(sample
);
5911 ok(ret
== 0, "Release returned %lu\n", ret
);
5913 status
= 0xdeadbeef;
5914 sample
= create_sample(NULL
, output_info
.cbSize
);
5915 memset(&output
, 0, sizeof(output
));
5916 output
.pSample
= sample
;
5917 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
5918 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5919 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
5920 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
5921 ok(status
== 0, "got status %#lx\n", status
);
5922 check_sample(sample
, NULL
, 0, NULL
);
5923 ret
= IMFSample_Release(sample
);
5924 ok(ret
== 0, "Release returned %lu\n", ret
);
5926 ret
= IMFTransform_Release(transform
);
5927 ok(ret
== 0, "Release returned %lu\n", ret
);
5933 static void test_wma_decoder(void)
5935 static const media_type_desc transform_inputs
[] =
5938 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5939 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
5942 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5943 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
5946 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5947 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
5950 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5951 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
5954 static const media_type_desc transform_outputs
[] =
5957 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5958 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5961 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5962 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5966 static const media_type_desc expect_available_inputs
[] =
5969 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5970 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
5971 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5974 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5975 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
5976 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5979 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5980 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
5981 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5984 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5985 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
5986 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5989 static const media_type_desc expect_available_outputs
[] =
5992 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5993 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5994 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
5995 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5996 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5997 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
5998 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
5999 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6000 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6001 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6004 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6005 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6006 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6007 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6008 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6009 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6010 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6011 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6012 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6013 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6017 const struct attribute_desc input_type_desc
[] =
6019 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6020 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6021 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
6022 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wma_block_size
),
6023 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6024 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6027 static const struct attribute_desc output_type_desc
[] =
6029 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6030 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6031 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
6032 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6033 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6034 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6035 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
6039 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
6040 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
6041 MFT_OUTPUT_STREAM_INFO output_info
;
6042 MFT_OUTPUT_DATA_BUFFER outputs
[2];
6043 MFT_INPUT_STREAM_INFO input_info
;
6044 MFT_OUTPUT_DATA_BUFFER output
;
6045 const BYTE
*wma_encoded_data
;
6046 ULONG wma_encoded_data_len
;
6047 IMFMediaType
*media_type
;
6048 IMFTransform
*transform
;
6056 hr
= CoInitialize(NULL
);
6057 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6059 if (!create_transform(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, L
"WMAudio Decoder MFT",
6060 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6061 &transform
, &class_id
))
6064 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6066 /* check default media types */
6068 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6069 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6070 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6071 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6072 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6073 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6076 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6078 winetest_push_context("in %lu", i
);
6079 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6080 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6081 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6082 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6083 ret
= IMFMediaType_Release(media_type
);
6084 ok(ret
== 0, "Release returned %lu\n", ret
);
6085 winetest_pop_context();
6088 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6090 ok(i
== 4, "%lu input media types\n", i
);
6092 /* setting output media type first doesn't work */
6094 hr
= MFCreateMediaType(&media_type
);
6095 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6096 init_media_type(media_type
, output_type_desc
, -1);
6097 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6098 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
6099 ret
= IMFMediaType_Release(media_type
);
6100 ok(ret
== 0, "Release returned %lu\n", ret
);
6102 /* check required input media type attributes */
6104 hr
= MFCreateMediaType(&media_type
);
6105 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6106 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6107 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6108 init_media_type(media_type
, input_type_desc
, 1);
6109 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6110 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6111 init_media_type(media_type
, input_type_desc
, 2);
6112 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
6114 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6115 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6116 init_media_type(media_type
, input_type_desc
, i
+ 1);
6118 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6119 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6120 ret
= IMFMediaType_Release(media_type
);
6121 ok(ret
== 0, "Release returned %lu\n", ret
);
6123 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6124 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6125 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6126 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6128 /* check new output media types */
6131 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6133 winetest_push_context("out %lu", i
);
6134 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6135 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6136 ret
= IMFMediaType_Release(media_type
);
6137 ok(ret
== 0, "Release returned %lu\n", ret
);
6138 winetest_pop_context();
6140 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6141 ok(i
== 2, "%lu output media types\n", i
);
6143 /* check required output media type attributes */
6145 hr
= MFCreateMediaType(&media_type
);
6146 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6147 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6148 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6149 init_media_type(media_type
, output_type_desc
, 1);
6150 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6151 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6152 init_media_type(media_type
, output_type_desc
, 2);
6153 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
6155 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6156 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
6157 init_media_type(media_type
, output_type_desc
, i
+ 1);
6159 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6160 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6161 ret
= IMFMediaType_Release(media_type
);
6162 ok(ret
== 0, "Release returned %lu\n", ret
);
6164 memset(&input_info
, 0xcd, sizeof(input_info
));
6165 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6166 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6167 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6168 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
6169 ok(input_info
.cbSize
== wma_block_size
, "got cbSize %lu\n", input_info
.cbSize
);
6170 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6171 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6173 memset(&output_info
, 0xcd, sizeof(output_info
));
6174 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6175 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6176 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6178 ok(output_info
.cbSize
== 0, "got cbSize %#lx\n", output_info
.cbSize
);
6179 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6181 /* MF_MT_AUDIO_AVG_BYTES_PER_SECOND isn't required by SetInputType, but is needed for the transform to work */
6183 hr
= MFCreateMediaType(&media_type
);
6184 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6185 init_media_type(media_type
, input_type_desc
, -1);
6186 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003);
6187 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
6188 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6189 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6191 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6192 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6194 init_media_type(media_type
, output_type_desc
, -1);
6195 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6196 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6197 ret
= IMFMediaType_Release(media_type
);
6198 ok(ret
== 0, "Release returned %lu\n", ret
);
6200 memset(&output_info
, 0xcd, sizeof(output_info
));
6201 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6202 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6203 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6204 ok(output_info
.cbSize
== sizeof(wma_decoded_data
), "got cbSize %#lx\n", output_info
.cbSize
);
6205 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6207 /* resource is generated using test_wma_encoder output file */
6208 resource
= FindResourceW(NULL
, L
"wmadata.bin", (const WCHAR
*)RT_RCDATA
);
6209 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6210 wma_encoded_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6211 wma_encoded_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6212 ok(wma_encoded_data_len
% wma_block_size
== 0, "got wma encoded length %lu\n", wma_encoded_data_len
);
6214 sample
= create_sample(wma_encoded_data
, wma_block_size
/ 2);
6215 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6216 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6217 ret
= IMFSample_Release(sample
);
6218 ok(ret
== 0, "Release returned %lu\n", ret
);
6219 sample
= create_sample(wma_encoded_data
, wma_block_size
+ 1);
6220 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6221 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6222 ret
= IMFSample_Release(sample
);
6223 ok(ret
== 0, "Release returned %lu\n", ret
);
6224 sample
= create_sample(wma_encoded_data
, wma_block_size
);
6225 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6226 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6227 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6228 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6229 ret
= IMFSample_Release(sample
);
6231 ok(ret
== 1, "Release returned %lu\n", ret
);
6233 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
6234 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
6236 status
= 0xdeadbeef;
6237 memset(&output
, 0, sizeof(output
));
6238 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6239 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6240 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6241 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6242 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6243 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6244 "got dwStatus %#lx\n", output
.dwStatus
);
6245 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6246 ok(status
== 0, "got status %#lx\n", status
);
6248 sample
= create_sample(wma_encoded_data
, wma_block_size
);
6249 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6250 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6251 ret
= IMFSample_Release(sample
);
6252 ok(ret
== 0, "Release returned %lu\n", ret
);
6254 status
= 0xdeadbeef;
6255 memset(&output
, 0, sizeof(output
));
6256 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6257 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6258 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6259 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6260 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6261 "got dwStatus %#lx\n", output
.dwStatus
);
6262 ok(status
== 0, "got status %#lx\n", status
);
6264 status
= 0xdeadbeef;
6265 memset(&output
, 0, sizeof(output
));
6266 output_info
.cbSize
= sizeof(wma_decoded_data
);
6267 sample
= create_sample(NULL
, output_info
.cbSize
);
6268 outputs
[0].pSample
= sample
;
6269 sample
= create_sample(NULL
, output_info
.cbSize
);
6270 outputs
[1].pSample
= sample
;
6271 hr
= IMFTransform_ProcessOutput(transform
, 0, 2, outputs
, &status
);
6272 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
6273 IMFSample_Release(outputs
[0].pSample
);
6274 IMFSample_Release(outputs
[1].pSample
);
6276 status
= 0xdeadbeef;
6277 output_info
.cbSize
= sizeof(wma_decoded_data
);
6278 sample
= create_sample(NULL
, output_info
.cbSize
);
6279 memset(&output
, 0, sizeof(output
));
6280 output
.pSample
= sample
;
6281 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6282 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6283 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6288 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6289 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| output
.dwStatus
== 0 ||
6290 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7) || output
.dwStatus
== 7) /* Win7 */,
6291 "got dwStatus %#lx\n", output
.dwStatus
);
6292 ok(status
== 0, "got status %#lx\n", status
);
6293 if (output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
6294 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)))
6296 check_sample(sample
, wma_decoded_data
, sizeof(wma_decoded_data
), NULL
);
6297 i
+= sizeof(wma_decoded_data
);
6303 /* FFmpeg doesn't seem to decode WMA buffers in the same way as native */
6305 hr
= IMFSample_GetTotalLength(sample
, &length
);
6306 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6308 ok(length
== sizeof(wma_decoded_data
) / 2, "got length %lu\n", length
);
6310 if (length
== sizeof(wma_decoded_data
) / 2)
6312 check_sample(sample
, wma_decoded_data
, sizeof(wma_decoded_data
) / 2, NULL
);
6313 i
+= sizeof(wma_decoded_data
) / 2;
6316 ret
= IMFSample_Release(sample
);
6317 ok(ret
== 0, "Release returned %lu\n", ret
);
6319 status
= 0xdeadbeef;
6320 sample
= create_sample(NULL
, output_info
.cbSize
);
6321 memset(&output
, 0, sizeof(output
));
6322 output
.pSample
= sample
;
6323 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6326 ok(i
== 0xe000, "ProcessOutput produced %#lx bytes\n", i
);
6328 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6329 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6330 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6331 ok(status
== 0, "got status %#lx\n", status
);
6332 ret
= IMFSample_Release(sample
);
6333 ok(ret
== 0, "Release returned %lu\n", ret
);
6335 status
= 0xdeadbeef;
6336 sample
= create_sample(NULL
, output_info
.cbSize
);
6337 memset(&output
, 0, sizeof(output
));
6338 output
.pSample
= sample
;
6339 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6340 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6341 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6342 ok(output
.dwStatus
== 0 ||
6343 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)) /* Win7 */,
6344 "got dwStatus %#lx\n", output
.dwStatus
);
6345 ok(status
== 0, "got status %#lx\n", status
);
6346 check_sample(sample
, NULL
, 0, NULL
);
6347 ret
= IMFSample_Release(sample
);
6348 ok(ret
== 0, "Release returned %lu\n", ret
);
6350 sample
= create_sample(wma_encoded_data
, wma_block_size
);
6351 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6352 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6354 ret
= IMFTransform_Release(transform
);
6355 ok(ret
== 0, "Release returned %lu\n", ret
);
6356 ret
= IMFSample_Release(sample
);
6357 ok(ret
== 0, "Release returned %lu\n", ret
);
6363 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
6364 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
6366 const BYTE
*sample_data
;
6368 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
6369 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
6370 sample_data
= *h264_buf
;
6375 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
6381 return create_sample(sample_data
, *h264_buf
- sample_data
);
6384 static void test_h264_decoder(void)
6386 static const media_type_desc transform_inputs
[] =
6389 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6390 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
6393 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6394 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
6397 static const media_type_desc transform_outputs
[] =
6400 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6401 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6404 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6405 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
6408 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6409 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
6412 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6413 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6416 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6417 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
6420 static const media_type_desc default_outputs
[] =
6423 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6424 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6425 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6426 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6427 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6428 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6429 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6430 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6433 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6434 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
6435 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6436 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6437 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6438 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6439 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6440 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6443 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6444 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
6445 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6446 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6447 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6448 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6449 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6450 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6453 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6454 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6455 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6456 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6457 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6458 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6459 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6460 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6463 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6464 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
6465 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6466 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6467 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
6468 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6469 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6470 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6473 static const media_type_desc default_outputs_extra
[] =
6476 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6477 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6478 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6481 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6482 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6483 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6486 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6487 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6488 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6491 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6492 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6493 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6496 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6497 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 4147200),
6498 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6501 static const media_type_desc default_outputs_win7
[] =
6504 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6505 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6508 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6509 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6512 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6513 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6516 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6517 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6520 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6521 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 4177920),
6524 static const struct attribute_desc input_type_desc
[] =
6526 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6527 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
6530 static const struct attribute_desc output_type_desc
[] =
6532 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6533 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6534 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6537 static const struct attribute_desc output_type_desc_win7
[] =
6539 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6540 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6541 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6544 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
6545 static const DWORD actual_width
= 96, actual_height
= 96;
6546 const media_type_desc actual_outputs
[] =
6549 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6550 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6551 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6552 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6553 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .todo_value
= TRUE
),
6554 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2, .todo_value
= TRUE
),
6555 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
, .todo_value
= TRUE
),
6556 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6557 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6558 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6559 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6560 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16, .todo
= TRUE
),
6563 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6564 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
6565 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6566 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6567 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .todo_value
= TRUE
),
6568 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2, .todo_value
= TRUE
),
6569 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
, .todo_value
= TRUE
),
6570 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6571 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6572 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6573 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6574 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16, .todo
= TRUE
),
6577 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6578 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
6579 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6580 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6581 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .todo_value
= TRUE
),
6582 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2, .todo_value
= TRUE
),
6583 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
, .todo_value
= TRUE
),
6584 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6585 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6586 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6587 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6588 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16, .todo
= TRUE
),
6591 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6592 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6593 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6594 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6595 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .todo_value
= TRUE
),
6596 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2, .todo_value
= TRUE
),
6597 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
, .todo_value
= TRUE
),
6598 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6599 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6600 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6601 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6602 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16, .todo
= TRUE
),
6605 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6606 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
6607 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6608 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6609 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .todo_value
= TRUE
),
6610 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2, .todo_value
= TRUE
),
6611 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2, .todo_value
= TRUE
),
6612 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6613 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6614 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6615 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6616 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16, .todo
= TRUE
),
6620 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
6621 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
6622 DWORD input_id
, output_id
, input_count
, output_count
;
6623 const BYTE
*h264_encoded_data
, *nv12_frame_data
;
6624 ULONG h264_encoded_data_len
, nv12_frame_len
;
6625 MFT_OUTPUT_STREAM_INFO output_info
;
6626 MFT_INPUT_STREAM_INFO input_info
;
6627 MFT_OUTPUT_DATA_BUFFER output
;
6628 IMFMediaBuffer
*media_buffer
;
6629 WCHAR output_path
[MAX_PATH
];
6630 IMFAttributes
*attributes
;
6631 IMFMediaType
*media_type
;
6632 IMFTransform
*transform
;
6633 DWORD status
, length
;
6634 ULONG i
, ret
, flags
;
6642 hr
= CoInitialize(NULL
);
6643 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6645 if (!create_transform(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, L
"Microsoft H264 Video Decoder MFT",
6646 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6647 &transform
, &class_id
))
6650 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
6651 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
6652 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
6653 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
6654 IMFAttributes_Release(attributes
);
6656 /* no output type is available before an input type is set */
6658 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6659 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6661 /* setting output media type first doesn't work */
6663 hr
= MFCreateMediaType(&media_type
);
6664 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6665 init_media_type(media_type
, default_outputs
[0], -1);
6666 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6667 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
6668 ret
= IMFMediaType_Release(media_type
);
6669 ok(ret
== 0, "Release returned %lu\n", ret
);
6671 /* check available input types */
6673 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
6674 memset(&input_info
, 0xcd, sizeof(input_info
));
6675 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6677 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6679 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6681 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
6683 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
6685 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6687 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6689 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
6690 memset(&output_info
, 0xcd, sizeof(output_info
));
6691 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6692 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6693 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
6694 ok(output_info
.cbSize
== 1920 * 1088 * 2, "got cbSize %#lx\n", output_info
.cbSize
);
6695 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6698 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6700 winetest_push_context("in %lu", i
);
6701 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6702 check_media_type(media_type
, transform_inputs
[i
], -1);
6703 ret
= IMFMediaType_Release(media_type
);
6704 ok(ret
== 0, "Release returned %lu\n", ret
);
6705 winetest_pop_context();
6707 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6708 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
6710 /* check required input media type attributes */
6712 hr
= MFCreateMediaType(&media_type
);
6713 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6714 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6715 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
6716 init_media_type(media_type
, input_type_desc
, 1);
6717 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6719 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6720 init_media_type(media_type
, input_type_desc
, 2);
6721 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6722 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6723 ret
= IMFMediaType_Release(media_type
);
6724 ok(ret
== 1, "Release returned %lu\n", ret
);
6726 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
6727 memset(&output_info
, 0xcd, sizeof(output_info
));
6728 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6729 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6730 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
6732 ok(output_info
.cbSize
== 1920 * 1080 * 2 || broken(output_info
.cbSize
== 1920 * 1088 * 2) /* Win7 */,
6733 "got cbSize %#lx\n", output_info
.cbSize
);
6734 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6736 /* output types can now be enumerated (though they are actually the same for all input types) */
6739 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6741 winetest_push_context("out %lu", i
);
6742 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6743 check_media_type(media_type
, default_outputs
[i
], -1);
6744 if (FAILED(hr
= IMFMediaType_GetItem(media_type
, &MF_MT_VIDEO_ROTATION
, NULL
)))
6745 check_media_type(media_type
, default_outputs_win7
[i
], -1);
6747 check_media_type(media_type
, default_outputs_extra
[i
], -1);
6748 ret
= IMFMediaType_Release(media_type
);
6749 ok(ret
== 0, "Release returned %lu\n", ret
);
6750 winetest_pop_context();
6752 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6753 ok(i
== 5, "%lu output media types\n", i
);
6755 /* check required output media type attributes */
6757 hr
= MFCreateMediaType(&media_type
);
6758 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6759 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6761 ok(hr
== E_INVALIDARG
, "SetOutputType returned %#lx.\n", hr
);
6762 init_media_type(media_type
, output_type_desc
, 1);
6763 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6765 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
6766 init_media_type(media_type
, output_type_desc
, 2);
6767 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
6769 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6771 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6772 init_media_type(media_type
, output_type_desc
, i
+ 1);
6774 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6775 if (broken(hr
== MF_E_INVALIDMEDIATYPE
))
6777 init_media_type(media_type
, output_type_desc_win7
, ARRAY_SIZE(output_type_desc_win7
) - 1);
6778 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6780 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6781 ret
= IMFMediaType_Release(media_type
);
6782 ok(ret
== 1, "Release returned %lu\n", ret
);
6784 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
6785 memset(&input_info
, 0xcd, sizeof(input_info
));
6786 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6787 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6788 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6789 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
6790 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
6791 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6792 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6794 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
6795 memset(&output_info
, 0xcd, sizeof(output_info
));
6796 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6797 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6798 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
6799 ok(output_info
.cbSize
== 1920 * 1080 * 2 || broken(output_info
.cbSize
== 1920 * 1088 * 2) /* Win7 */,
6800 "got cbSize %#lx\n", output_info
.cbSize
);
6801 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6803 input_count
= output_count
= 0xdeadbeef;
6804 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
6806 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
6808 ok(input_count
== 1, "got input_count %lu\n", input_count
);
6810 ok(output_count
== 1, "got output_count %lu\n", output_count
);
6811 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
6812 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
6814 resource
= FindResourceW(NULL
, L
"h264data.bin", (const WCHAR
*)RT_RCDATA
);
6815 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6816 h264_encoded_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6817 h264_encoded_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6819 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
6820 * IMFTransform_ProcessOutput needs a sample or returns an error */
6823 memset(&output
, 0, sizeof(output
));
6824 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6825 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6826 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6827 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6828 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6829 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6830 ok(status
== 0, "got status %#lx\n", status
);
6833 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
6837 memset(&output
, 0, sizeof(output
));
6838 output
.pSample
= create_sample(NULL
, output_info
.cbSize
);
6839 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6840 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
6841 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6842 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6843 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
6844 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6845 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6846 ok(status
== 0, "got status %#lx\n", status
);
6847 check_sample(output
.pSample
, NULL
, 0, NULL
);
6848 ret
= IMFSample_Release(output
.pSample
);
6849 ok(ret
== 0, "Release returned %lu\n", ret
);
6851 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6852 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6853 ret
= IMFSample_Release(sample
);
6854 ok(ret
<= 1, "Release returned %lu\n", ret
);
6855 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
6857 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6858 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6859 ret
= IMFSample_Release(sample
);
6860 ok(ret
<= 1, "Release returned %lu\n", ret
);
6861 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
6864 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6865 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6868 ok(i
== 2, "got %lu iterations\n", i
);
6870 ok(h264_encoded_data_len
== 48194, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
6872 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
6873 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6874 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
6876 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
,
6877 "got dwStatus %#lx\n", output
.dwStatus
);
6878 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6880 ok(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
6881 "got status %#lx\n", status
);
6882 if (status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
)
6883 check_sample(output
.pSample
, NULL
, 0, NULL
);
6884 ret
= IMFSample_Release(output
.pSample
);
6885 ok(ret
== 0, "Release returned %lu\n", ret
);
6887 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
6888 memset(&output_info
, 0xcd, sizeof(output_info
));
6889 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6890 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6891 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
6893 ok(output_info
.cbSize
== actual_width
* actual_height
* 2, "got cbSize %#lx\n", output_info
.cbSize
);
6894 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6897 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6899 winetest_push_context("out %lu", i
);
6900 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6901 check_media_type(media_type
, actual_outputs
[i
], -1);
6902 ret
= IMFMediaType_Release(media_type
);
6903 ok(ret
== 0, "Release returned %lu\n", ret
);
6904 winetest_pop_context();
6906 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6907 ok(i
== 5, "%lu output media types\n", i
);
6909 /* and generate a new one as well in a temporary directory */
6910 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
6911 lstrcatW(output_path
, L
"nv12frame.bin");
6912 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
6913 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
6915 resource
= FindResourceW(NULL
, L
"nv12frame.bin", (const WCHAR
*)RT_RCDATA
);
6916 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6917 nv12_frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6918 nv12_frame_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6919 ok(nv12_frame_len
== actual_width
* actual_height
* 3 / 2, "got frame length %lu\n", nv12_frame_len
);
6922 memset(&output
, 0, sizeof(output
));
6923 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
6924 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6926 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6927 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6928 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
6929 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6930 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6931 ok(status
== 0, "got status %#lx\n", status
);
6934 /* Win8 and before pad the data with garbage instead of original
6935 * buffer data, make sure it's consistent. */
6936 hr
= IMFSample_ConvertToContiguousBuffer(output
.pSample
, &media_buffer
);
6937 ok(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
6938 hr
= IMFMediaBuffer_Lock(media_buffer
, &data
, NULL
, &length
);
6939 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
6941 ok(length
== nv12_frame_len
, "got length %lu\n", length
);
6942 if (length
== nv12_frame_len
)
6944 for (i
= 0; i
< actual_aperture
.Area
.cy
; ++i
)
6946 memset(data
+ actual_width
* i
+ actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
6947 memset(data
+ actual_width
* (actual_height
+ i
) + actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
6949 memset(data
+ actual_width
* actual_aperture
.Area
.cy
, 0xcd, (actual_height
- actual_aperture
.Area
.cy
) * actual_width
);
6950 memset(data
+ actual_width
* (actual_height
+ actual_aperture
.Area
.cy
/ 2), 0xcd, (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
);
6952 hr
= IMFMediaBuffer_Unlock(media_buffer
);
6953 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
6954 IMFMediaBuffer_Release(media_buffer
);
6956 if (length
== nv12_frame_len
)
6957 check_sample(output
.pSample
, nv12_frame_data
, nv12_frame_len
, output_file
);
6959 ret
= IMFSample_Release(output
.pSample
);
6960 ok(ret
== 0, "Release returned %lu\n", ret
);
6962 trace("created %s\n", debugstr_w(output_path
));
6963 CloseHandle(output_file
);
6965 ret
= IMFTransform_Release(transform
);
6966 ok(ret
== 0, "Release returned %lu\n", ret
);
6967 ret
= IMFSample_Release(sample
);
6968 ok(ret
== 0, "Release returned %lu\n", ret
);
6980 win_skip("Skipping tests on Vista.\n");
6985 test_topology_tee_node();
6986 test_topology_loader();
6987 test_topology_loader_evr();
6988 test_MFGetService();
6989 test_sequencer_source();
6990 test_media_session();
6991 test_media_session_rate_control();
6992 test_MFShutdownObject();
6993 test_presentation_clock();
6994 test_sample_grabber();
6995 test_sample_grabber_is_mediatype_supported();
6996 test_video_processor();
6997 test_quality_manager();
7000 test_MFCreateSimpleTypeHandler();
7001 test_MFGetSupportedMimeTypes();
7002 test_MFGetSupportedSchemes();
7003 test_sample_copier();
7004 test_sample_copier_output_processing();
7005 test_MFGetTopoNodeCurrentType();
7006 test_MFRequireProtectedEnvironment();
7009 test_h264_decoder();