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
29 #include "d3d9types.h"
36 #include "wmcodecdsp.h"
38 #include "propvarutil.h"
40 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
41 DEFINE_GUID(MFVideoFormat_P208
, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
42 DEFINE_GUID(MFVideoFormat_ABGR32
, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
43 DEFINE_GUID(CLSID_WINEAudioConverter
, 0x6a170414, 0xaad9, 0x4693, 0xb8, 0x06, 0x3a, 0x0c, 0x47, 0xc5, 0x70, 0xd6);
45 DEFINE_GUID(DMOVideoFormat_RGB32
, D3DFMT_X8R8G8B8
, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
46 DEFINE_GUID(DMOVideoFormat_RGB24
, D3DFMT_R8G8B8
, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
47 DEFINE_GUID(DMOVideoFormat_RGB565
, D3DFMT_R5G6B5
, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
48 DEFINE_GUID(DMOVideoFormat_RGB555
, D3DFMT_X1R5G5B5
, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
49 DEFINE_GUID(DMOVideoFormat_RGB8
, D3DFMT_P8
, 0x524f, 0x11ce, 0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70);
58 #include "mmdeviceapi.h"
59 #include "audioclient.h"
64 #include "wine/test.h"
66 static HRESULT (WINAPI
*pMFCreateSampleCopierMFT
)(IMFTransform
**copier
);
67 static HRESULT (WINAPI
*pMFGetTopoNodeCurrentType
)(IMFTopologyNode
*node
, DWORD stream
, BOOL output
, IMFMediaType
**type
);
69 static BOOL has_video_processor
;
70 static BOOL
is_vista(void)
72 return !pMFGetTopoNodeCurrentType
;
75 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
76 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
80 refcount
= IUnknown_Release(obj
);
81 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
85 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
86 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
88 IUnknown
*iface
= iface_ptr
;
89 HRESULT hr
, expected_hr
;
92 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
94 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
95 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
97 IUnknown_Release(unk
);
100 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
101 static void check_service_interface_(unsigned int line
, void *iface_ptr
, REFGUID service
, REFIID iid
, BOOL supported
)
103 IUnknown
*iface
= iface_ptr
;
104 HRESULT hr
, expected_hr
;
107 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
109 hr
= MFGetService(iface
, service
, iid
, (void **)&unk
);
110 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
112 IUnknown_Release(unk
);
115 static void check_dmo(const GUID
*class_id
, const WCHAR
*expect_name
, const GUID
*expect_major_type
,
116 const GUID
*expect_input
, ULONG expect_input_count
, const GUID
*expect_output
, ULONG expect_output_count
)
118 ULONG i
, input_count
= 0, output_count
= 0;
119 DMO_PARTIAL_MEDIATYPE output
[32] = {{{0}}};
120 DMO_PARTIAL_MEDIATYPE input
[32] = {{{0}}};
124 winetest_push_context("%s", debugstr_w(expect_name
));
126 hr
= DMOGetName(class_id
, name
);
127 ok(hr
== S_OK
, "DMOGetName returned %#lx\n", hr
);
128 todo_wine_if(!wcscmp(expect_name
, L
"WMAudio Decoder DMO"))
129 ok(!wcscmp(name
, expect_name
), "got name %s\n", debugstr_w(name
));
131 hr
= DMOGetTypes(class_id
, ARRAY_SIZE(input
), &input_count
, input
,
132 ARRAY_SIZE(output
), &output_count
, output
);
133 ok(hr
== S_OK
, "DMOGetTypes returned %#lx\n", hr
);
134 ok(input_count
== expect_input_count
, "got input_count %lu\n", input_count
);
135 ok(output_count
== expect_output_count
, "got output_count %lu\n", output_count
);
137 for (i
= 0; i
< input_count
; ++i
)
139 winetest_push_context("in %lu", i
);
140 ok(IsEqualGUID(&input
[i
].type
, expect_major_type
),
141 "got type %s\n", debugstr_guid(&input
[i
].type
));
142 ok(IsEqualGUID(&input
[i
].subtype
, expect_input
+ i
),
143 "got subtype %s\n", debugstr_guid(&input
[i
].subtype
));
144 winetest_pop_context();
147 for (i
= 0; i
< output_count
; ++i
)
149 winetest_push_context("out %lu", i
);
150 ok(IsEqualGUID(&output
[i
].type
, expect_major_type
),
151 "got type %s\n", debugstr_guid(&output
[i
].type
));
152 ok(IsEqualGUID(&output
[i
].subtype
, expect_output
+ i
),
153 "got subtype %s\n", debugstr_guid( &output
[i
].subtype
));
154 winetest_pop_context();
157 winetest_pop_context();
160 struct attribute_desc
169 typedef struct attribute_desc media_type_desc
[32];
171 #define ATTR_GUID(k, g, ...) {.key = &k, .name = #k, {.vt = VT_CLSID, .puuid = (GUID *)&g}, __VA_ARGS__ }
172 #define ATTR_UINT32(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI4, .ulVal = v}, __VA_ARGS__ }
173 #define ATTR_BLOB(k, p, n, ...) {.key = &k, .name = #k, {.vt = VT_VECTOR | VT_UI1, .caub = {.pElems = (void *)p, .cElems = n}}, __VA_ARGS__ }
174 #define ATTR_RATIO(k, n, d, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.HighPart = n, .LowPart = d}}, .ratio = TRUE, __VA_ARGS__ }
175 #define ATTR_UINT64(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.QuadPart = v}}, __VA_ARGS__ }
177 #define check_media_type(a, b, c) check_attributes_(__LINE__, (IMFAttributes *)a, b, c)
178 #define check_attributes(a, b, c) check_attributes_(__LINE__, a, b, c)
179 static void check_attributes_(int line
, IMFAttributes
*attributes
, const struct attribute_desc
*desc
, ULONG limit
)
181 char buffer
[256], *buf
= buffer
;
186 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
188 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
189 todo_wine_if(desc
[i
].todo
)
190 ok_(__FILE__
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
191 if (hr
!= S_OK
) continue;
195 default: sprintf(buffer
, "??"); break;
196 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
197 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
200 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
202 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
204 case VT_VECTOR
| VT_UI1
:
205 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
206 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
207 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
208 if (value
.caub
.cElems
> 16)
209 buf
+= sprintf(buf
, "...}");
211 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
215 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
216 todo_wine_if(desc
[i
].todo_value
)
217 ok_(__FILE__
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
218 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
222 static HWND
create_window(void)
224 RECT r
= {0, 0, 640, 480};
226 AdjustWindowRect(&r
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
, FALSE
);
228 return CreateWindowA("static", "mf_test", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
229 0, 0, r
.right
- r
.left
, r
.bottom
- r
.top
, NULL
, NULL
, NULL
, NULL
);
232 static BOOL
create_transform(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
233 MFT_REGISTER_TYPE_INFO
*output_type
, const WCHAR
*expect_name
, const GUID
*expect_major_type
,
234 const GUID
*expect_input
, ULONG expect_input_count
, const GUID
*expect_output
, ULONG expect_output_count
,
235 IMFTransform
**transform
, const GUID
*expect_class_id
, GUID
*class_id
)
237 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
238 UINT32 input_count
= 0, output_count
= 0, count
= 0, i
;
239 GUID
*class_ids
= NULL
;
243 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
244 if (FAILED(hr
) || count
== 0)
247 win_skip("Failed to enumerate %s, skipping tests.\n", debugstr_w(expect_name
));
251 ok(hr
== S_OK
, "MFTEnum returned %lx\n", hr
);
252 for (i
= 0; i
< count
; ++i
)
254 if (IsEqualGUID(expect_class_id
, class_ids
+ i
))
257 ok(i
< count
, "failed to find %s transform\n", debugstr_w(expect_name
));
258 *class_id
= class_ids
[i
];
259 CoTaskMemFree(class_ids
);
260 ok(IsEqualGUID(class_id
, expect_class_id
), "got class id %s\n", debugstr_guid(class_id
));
262 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
266 win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name
));
270 ok(hr
== S_OK
, "MFTEnum returned %lx\n", hr
);
271 ok(!wcscmp(name
, expect_name
), "got name %s\n", debugstr_w(name
));
272 ok(input_count
== expect_input_count
, "got input_count %u\n", input_count
);
273 for (i
= 0; i
< input_count
; ++i
)
275 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect_major_type
),
276 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
277 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect_input
+ i
),
278 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
280 ok(output_count
== expect_output_count
, "got output_count %u\n", output_count
);
281 for (i
= 0; i
< output_count
; ++i
)
283 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect_major_type
),
284 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
285 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect_output
+ i
),
286 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
288 CoTaskMemFree(output_types
);
289 CoTaskMemFree(input_types
);
293 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)transform
);
297 win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name
));
304 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
306 if (IsEqualIID(riid
, &IID_IUnknown
))
309 IUnknown_AddRef(iface
);
314 return E_NOINTERFACE
;
317 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
322 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
327 static const IUnknownVtbl test_unk_vtbl
=
329 test_unk_QueryInterface
,
334 static void test_topology(void)
336 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
337 IMFCollection
*collection
, *collection2
;
338 IUnknown test_unk2
= { &test_unk_vtbl
};
339 IUnknown test_unk
= { &test_unk_vtbl
};
340 IMFTopologyNode
*node
, *node2
, *node3
;
341 IMFTopology
*topology
, *topology2
;
342 DWORD size
, io_count
, index
;
343 MF_TOPOLOGY_TYPE node_type
;
351 hr
= MFCreateTopology(NULL
);
352 ok(hr
== E_POINTER
, "got %#lx\n", hr
);
354 hr
= MFCreateTopology(&topology
);
355 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
356 hr
= IMFTopology_GetTopologyID(topology
, &id
);
357 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
358 ok(id
== 1, "Unexpected id.\n");
360 hr
= MFCreateTopology(&topology2
);
361 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
362 hr
= IMFTopology_GetTopologyID(topology2
, &id
);
363 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
364 ok(id
== 2, "Unexpected id.\n");
366 ref
= IMFTopology_Release(topology
);
367 ok(ref
== 0, "Release returned %ld\n", ref
);
369 hr
= MFCreateTopology(&topology
);
370 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
371 hr
= IMFTopology_GetTopologyID(topology
, &id
);
372 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
373 ok(id
== 3, "Unexpected id.\n");
375 ref
= IMFTopology_Release(topology2
);
376 ok(ref
== 0, "Release returned %ld\n", ref
);
378 /* No attributes by default. */
379 for (node_type
= MF_TOPOLOGY_OUTPUT_NODE
; node_type
< MF_TOPOLOGY_TEE_NODE
; ++node_type
)
381 hr
= MFCreateTopologyNode(node_type
, &node
);
382 ok(hr
== S_OK
, "Failed to create a node for type %d, hr %#lx.\n", node_type
, hr
);
383 hr
= IMFTopologyNode_GetCount(node
, &count
);
384 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
385 ok(!count
, "Unexpected attribute count %u.\n", count
);
386 ref
= IMFTopologyNode_Release(node
);
387 ok(ref
== 0, "Release returned %ld\n", ref
);
390 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, NULL
);
391 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
393 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
394 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
396 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
397 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
399 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
400 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
401 ok(((id
>> 32) == GetCurrentProcessId()) && !!(id
& 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id
));
403 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
404 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
406 hr
= IMFTopology_GetNodeCount(topology
, NULL
);
407 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
409 hr
= IMFTopology_AddNode(topology
, NULL
);
410 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
413 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
414 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
415 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
417 /* Same id, different nodes. */
418 hr
= IMFTopology_AddNode(topology
, node
);
419 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
422 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
423 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
424 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
426 hr
= IMFTopology_AddNode(topology
, node2
);
427 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
428 ref
= IMFTopologyNode_Release(node2
);
429 ok(ref
== 0, "Release returned %ld\n", ref
);
431 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
432 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
433 ok(node2
== node
, "Unexpected node.\n");
434 IMFTopologyNode_Release(node2
);
436 /* Change node id, add it again. */
437 hr
= IMFTopologyNode_SetTopoNodeID(node
, ++id
);
438 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
440 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
441 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
442 ok(node2
== node
, "Unexpected node.\n");
443 IMFTopologyNode_Release(node2
);
445 hr
= IMFTopology_GetNodeByID(topology
, id
+ 1, &node2
);
446 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
448 hr
= IMFTopology_AddNode(topology
, node
);
449 ok(hr
== E_INVALIDARG
, "Failed to add a node, hr %#lx.\n", hr
);
451 hr
= IMFTopology_GetNode(topology
, 0, &node2
);
452 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
453 ok(node2
== node
, "Unexpected node.\n");
454 IMFTopologyNode_Release(node2
);
456 hr
= IMFTopology_GetNode(topology
, 1, NULL
);
457 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
459 hr
= IMFTopology_GetNode(topology
, 1, &node2
);
460 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
462 hr
= IMFTopology_GetNode(topology
, -2, &node2
);
463 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
465 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
466 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
467 hr
= IMFTopology_AddNode(topology
, node2
);
468 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
469 ref
= IMFTopologyNode_Release(node2
);
470 ok(ref
== 1, "Release returned %ld\n", ref
);
473 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
474 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
475 ok(node_count
== 2, "Unexpected node count %u.\n", node_count
);
477 /* Remove with detached node, existing id. */
478 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
479 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
480 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
481 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
482 hr
= IMFTopology_RemoveNode(topology
, node2
);
483 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
484 ref
= IMFTopologyNode_Release(node2
);
485 ok(ref
== 0, "Release returned %ld\n", ref
);
487 hr
= IMFTopology_RemoveNode(topology
, node
);
488 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
491 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
492 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
493 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
495 hr
= IMFTopology_Clear(topology
);
496 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
499 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
500 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
501 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
503 hr
= IMFTopology_Clear(topology
);
504 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
506 hr
= IMFTopologyNode_SetTopoNodeID(node
, 123);
507 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
509 ref
= IMFTopologyNode_Release(node
);
510 ok(ref
== 0, "Release returned %ld\n", ref
);
512 /* Change id for attached node. */
513 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
514 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
516 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
517 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
519 hr
= IMFTopology_AddNode(topology
, node
);
520 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
522 hr
= IMFTopology_AddNode(topology
, node2
);
523 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
525 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
526 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
528 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
529 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
531 hr
= IMFTopology_GetNodeByID(topology
, id
, &node3
);
532 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
533 ok(node3
== node
, "Unexpected node.\n");
534 IMFTopologyNode_Release(node3
);
536 /* Source/output collections. */
537 hr
= IMFTopology_Clear(topology
);
538 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
540 ref
= IMFTopologyNode_Release(node
);
541 ok(ref
== 0, "Release returned %ld\n", ref
);
542 ref
= IMFTopologyNode_Release(node2
);
543 ok(ref
== 0, "Release returned %ld\n", ref
);
545 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
546 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
548 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
549 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
550 ok(!!collection
, "Unexpected object pointer.\n");
552 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection2
);
553 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
554 ok(!!collection2
, "Unexpected object pointer.\n");
555 ok(collection2
!= collection
, "Expected cloned collection.\n");
557 hr
= IMFCollection_GetElementCount(collection
, &size
);
558 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
559 ok(!size
, "Unexpected item count.\n");
561 EXPECT_REF(collection
, 1);
562 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)collection
);
563 ok(hr
== S_OK
, "Failed to add element, hr %#lx.\n", hr
);
564 EXPECT_REF(collection
, 2);
566 hr
= IMFCollection_GetElementCount(collection
, &size
);
567 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
568 ok(size
== 1, "Unexpected item count.\n");
570 /* Empty collection to stop referencing itself */
571 hr
= IMFCollection_RemoveAllElements(collection
);
572 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
574 hr
= IMFCollection_GetElementCount(collection2
, &size
);
575 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
576 ok(!size
, "Unexpected item count.\n");
578 ref
= IMFCollection_Release(collection2
);
579 ok(ref
== 0, "Release returned %ld\n", ref
);
580 ref
= IMFCollection_Release(collection
);
581 ok(ref
== 0, "Release returned %ld\n", ref
);
583 /* Add some nodes. */
584 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
585 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
587 hr
= IMFTopology_GetOutputNodeCollection(topology
, NULL
);
588 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
590 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
591 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
592 hr
= IMFTopology_AddNode(topology
, node
);
593 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
594 IMFTopologyNode_Release(node
);
596 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
597 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
598 ok(!!collection
, "Unexpected object pointer.\n");
599 hr
= IMFCollection_GetElementCount(collection
, &size
);
600 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
601 ok(size
== 1, "Unexpected item count.\n");
602 ref
= IMFCollection_Release(collection
);
603 ok(ref
== 0, "Release returned %ld\n", ref
);
605 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
606 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
607 hr
= IMFTopology_AddNode(topology
, node
);
608 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
609 IMFTopologyNode_Release(node
);
611 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
612 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
613 ok(!!collection
, "Unexpected object pointer.\n");
614 hr
= IMFCollection_GetElementCount(collection
, &size
);
615 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
616 ok(size
== 1, "Unexpected item count.\n");
617 ref
= IMFCollection_Release(collection
);
618 ok(ref
== 0, "Release returned %ld\n", ref
);
620 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
621 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
622 hr
= IMFTopology_AddNode(topology
, node
);
623 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
624 IMFTopologyNode_Release(node
);
626 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
627 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
628 ok(!!collection
, "Unexpected object pointer.\n");
629 hr
= IMFCollection_GetElementCount(collection
, &size
);
630 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
631 ok(size
== 1, "Unexpected item count.\n");
632 ref
= IMFCollection_Release(collection
);
633 ok(ref
== 0, "Release returned %ld\n", ref
);
635 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
636 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
637 hr
= IMFTopology_AddNode(topology
, node
);
638 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
640 /* Associated object. */
641 hr
= IMFTopologyNode_SetObject(node
, NULL
);
642 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
644 hr
= IMFTopologyNode_GetObject(node
, NULL
);
645 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
647 object
= (void *)0xdeadbeef;
648 hr
= IMFTopologyNode_GetObject(node
, &object
);
649 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
650 ok(!object
, "Unexpected object %p.\n", object
);
652 hr
= IMFTopologyNode_SetObject(node
, &test_unk
);
653 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
655 hr
= IMFTopologyNode_GetObject(node
, &object
);
656 ok(hr
== S_OK
, "Failed to get object, hr %#lx.\n", hr
);
657 ok(object
== &test_unk
, "Unexpected object %p.\n", object
);
658 IUnknown_Release(object
);
660 hr
= IMFTopologyNode_SetObject(node
, &test_unk2
);
661 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
663 hr
= IMFTopologyNode_GetCount(node
, &count
);
664 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
665 ok(count
== 0, "Unexpected attribute count %u.\n", count
);
667 hr
= IMFTopologyNode_SetGUID(node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &MF_TOPONODE_TRANSFORM_OBJECTID
);
668 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
670 hr
= IMFTopologyNode_SetObject(node
, NULL
);
671 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
673 object
= (void *)0xdeadbeef;
674 hr
= IMFTopologyNode_GetObject(node
, &object
);
675 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
676 ok(!object
, "Unexpected object %p.\n", object
);
678 hr
= IMFTopologyNode_GetCount(node
, &count
);
679 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
680 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
682 /* Preferred stream types. */
683 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
684 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
685 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
687 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype
);
688 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
690 hr
= MFCreateMediaType(&mediatype
);
691 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
693 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
694 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
696 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
697 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
698 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
699 IMFMediaType_Release(mediatype2
);
701 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
702 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
704 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
705 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
706 ok(!mediatype2
, "Unexpected mediatype instance.\n");
708 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
709 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
711 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
712 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
714 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
715 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
716 ok(io_count
== 2, "Unexpected count %lu.\n", io_count
);
718 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
719 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
720 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
722 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, mediatype
);
723 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
725 ref
= IMFTopologyNode_Release(node
);
726 ok(ref
== 1, "Release returned %ld\n", ref
);
729 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
730 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
732 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
733 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
735 hr
= IMFTopologyNode_SetOutputPrefType(node
, 2, mediatype
);
736 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
738 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
739 ok(hr
== E_FAIL
, "Failed to get preferred type, hr %#lx.\n", hr
);
740 ok(!mediatype2
, "Unexpected mediatype instance.\n");
742 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
743 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
744 ok(io_count
== 3, "Unexpected count %lu.\n", io_count
);
746 ref
= IMFTopologyNode_Release(node
);
747 ok(ref
== 0, "Release returned %ld\n", ref
);
750 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
751 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
753 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
754 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
756 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
757 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
758 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
759 IMFMediaType_Release(mediatype2
);
761 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
762 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
764 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
765 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
766 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
768 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
769 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
771 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
772 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
774 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
775 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
777 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
778 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
780 hr
= MFCreateMediaType(&mediatype2
);
781 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
783 /* Changing output type does not change input type. */
784 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype2
);
785 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
787 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype3
);
788 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
789 ok(mediatype3
== mediatype
, "Unexpected mediatype instance.\n");
790 IMFMediaType_Release(mediatype3
);
792 IMFMediaType_Release(mediatype2
);
794 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
795 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
796 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
798 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
799 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
800 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
802 ref
= IMFTopologyNode_Release(node
);
803 ok(ref
== 0, "Release returned %ld\n", ref
);
805 /* Transform node. */
806 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
807 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
809 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
810 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
812 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
813 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
814 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
816 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
817 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
819 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
820 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
821 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
823 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
824 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
825 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
827 ref
= IMFTopologyNode_Release(node
);
828 ok(ref
== 0, "Release returned %ld\n", ref
);
830 IMFMediaType_Release(mediatype
);
832 hr
= IMFTopology_GetOutputNodeCollection(topology
, &collection
);
833 ok(hr
== S_OK
|| broken(hr
== E_FAIL
) /* before Win8 */, "Failed to get output node collection, hr %#lx.\n", hr
);
836 ok(!!collection
, "Unexpected object pointer.\n");
837 hr
= IMFCollection_GetElementCount(collection
, &size
);
838 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
839 ok(size
== 1, "Unexpected item count.\n");
840 ref
= IMFCollection_Release(collection
);
841 ok(ref
== 0, "Release returned %ld\n", ref
);
844 ref
= IMFTopology_Release(topology
);
845 ok(ref
== 0, "Release returned %ld\n", ref
);
848 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
849 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
851 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
852 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
855 EXPECT_REF(node2
, 1);
857 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
858 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
861 EXPECT_REF(node2
, 2);
863 IMFTopologyNode_Release(node
);
866 EXPECT_REF(node2
, 2);
868 IMFTopologyNode_Release(node2
);
871 EXPECT_REF(node2
, 1);
873 hr
= IMFTopologyNode_GetNodeType(node2
, &node_type
);
874 ok(hr
== S_OK
, "Failed to get node type, hr %#lx.\n", hr
);
876 IMFTopologyNode_Release(node
);
878 /* Connect within topology. */
879 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
880 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
882 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
883 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
885 hr
= MFCreateTopology(&topology
);
886 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
888 hr
= IMFTopology_AddNode(topology
, node
);
889 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
891 hr
= IMFTopology_AddNode(topology
, node2
);
892 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
895 EXPECT_REF(node2
, 2);
897 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
898 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
901 EXPECT_REF(node2
, 3);
903 hr
= IMFTopology_Clear(topology
);
904 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
907 EXPECT_REF(node2
, 1);
909 /* Removing connected node breaks connection. */
910 hr
= IMFTopology_AddNode(topology
, node
);
911 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
913 hr
= IMFTopology_AddNode(topology
, node2
);
914 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
916 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
917 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
919 hr
= IMFTopology_RemoveNode(topology
, node
);
920 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
923 EXPECT_REF(node2
, 2);
925 hr
= IMFTopologyNode_GetOutput(node
, 0, &node3
, &index
);
926 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
928 hr
= IMFTopology_AddNode(topology
, node
);
929 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
931 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
932 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
934 hr
= IMFTopology_RemoveNode(topology
, node2
);
935 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
938 EXPECT_REF(node2
, 1);
940 IMFTopologyNode_Release(node
);
941 IMFTopologyNode_Release(node2
);
943 /* Cloning nodes of different types. */
944 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
945 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
947 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
948 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
950 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
951 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
953 ref
= IMFTopologyNode_Release(node2
);
954 ok(ref
== 0, "Release returned %ld\n", ref
);
956 /* Cloning preferred types. */
957 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
958 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
960 hr
= MFCreateMediaType(&mediatype
);
961 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
963 hr
= IMFTopologyNode_SetOutputPrefType(node2
, 0, mediatype
);
964 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
966 /* Vista checks for additional attributes. */
967 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
968 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
970 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
971 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
972 ok(mediatype
== mediatype2
, "Unexpected media type.\n");
974 IMFMediaType_Release(mediatype2
);
976 ref
= IMFTopologyNode_Release(node2
);
977 ok(ref
== 0, "Release returned %ld\n", ref
);
979 IMFMediaType_Release(mediatype
);
981 /* Existing preferred types are not cleared. */
982 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
983 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
985 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
986 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
987 ok(io_count
== 1, "Unexpected output count.\n");
989 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
990 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
992 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
993 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
994 ok(io_count
== 1, "Unexpected output count.\n");
996 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
997 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
998 ok(!!mediatype2
, "Unexpected media type.\n");
999 IMFMediaType_Release(mediatype2
);
1001 hr
= IMFTopologyNode_CloneFrom(node2
, node
);
1002 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
1004 hr
= IMFTopologyNode_GetOutputCount(node2
, &io_count
);
1005 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
1006 ok(io_count
== 1, "Unexpected output count.\n");
1008 ref
= IMFTopologyNode_Release(node2
);
1009 ok(ref
== 0, "Release returned %ld\n", ref
);
1010 ref
= IMFTopologyNode_Release(node
);
1011 ok(ref
== 0, "Release returned %ld\n", ref
);
1013 /* Add one node, connect to another that hasn't been added. */
1014 hr
= IMFTopology_Clear(topology
);
1015 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
1017 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
1018 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1020 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
1021 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1023 hr
= IMFTopology_AddNode(topology
, node
);
1024 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1026 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1027 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1028 ok(node_count
== 1, "Unexpected node count.\n");
1030 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 0);
1031 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1033 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1034 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1035 ok(node_count
== 1, "Unexpected node count.\n");
1037 /* Add same node to different topologies. */
1038 hr
= IMFTopology_Clear(topology
);
1039 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
1041 hr
= MFCreateTopology(&topology2
);
1042 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
1044 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
1045 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1047 hr
= IMFTopology_AddNode(topology
, node
);
1048 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1049 EXPECT_REF(node
, 2);
1051 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1052 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1053 ok(node_count
== 1, "Unexpected node count.\n");
1055 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
1056 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1057 ok(node_count
== 0, "Unexpected node count.\n");
1059 hr
= IMFTopology_AddNode(topology2
, node
);
1060 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1061 EXPECT_REF(node
, 3);
1063 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1064 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1065 ok(node_count
== 1, "Unexpected node count.\n");
1067 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
1068 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1069 ok(node_count
== 1, "Unexpected node count.\n");
1071 ref
= IMFTopology_Release(topology2
);
1072 ok(ref
== 0, "Release returned %ld\n", ref
);
1073 ref
= IMFTopology_Release(topology
);
1074 ok(ref
== 0, "Release returned %ld\n", ref
);
1076 ref
= IMFTopologyNode_Release(node
);
1077 ok(ref
== 0, "Release returned %ld\n", ref
);
1078 ref
= IMFTopologyNode_Release(node2
);
1079 ok(ref
== 0, "Release returned %ld\n", ref
);
1082 static void test_topology_tee_node(void)
1084 IMFTopologyNode
*src_node
, *tee_node
;
1085 IMFMediaType
*mediatype
, *mediatype2
;
1086 IMFTopology
*topology
;
1091 hr
= MFCreateTopology(&topology
);
1092 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
1094 hr
= MFCreateMediaType(&mediatype
);
1095 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1097 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &tee_node
);
1098 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1100 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
1101 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1103 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 0, mediatype
);
1104 ok(hr
== S_OK
, "Failed to set type, hr %#lx.\n", hr
);
1106 /* Even though tee node has only one input and source has only one output,
1107 it's possible to connect to higher inputs/outputs. */
1109 /* SRC(0) -> TEE(0) */
1110 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 0);
1111 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1113 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
1114 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1115 ok(count
== 1, "Unexpected count %lu.\n", count
);
1117 hr
= IMFTopologyNode_GetInputPrefType(tee_node
, 0, &mediatype2
);
1118 ok(hr
== S_OK
, "Failed to get type, hr %#lx.\n", hr
);
1119 ok(mediatype2
== mediatype
, "Unexpected type.\n");
1120 IMFMediaType_Release(mediatype2
);
1122 /* SRC(0) -> TEE(1) */
1123 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 1);
1124 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1126 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
1127 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1128 ok(count
== 2, "Unexpected count %lu.\n", count
);
1130 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 1, mediatype
);
1131 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
1133 /* SRC(1) -> TEE(1) */
1134 hr
= IMFTopologyNode_ConnectOutput(src_node
, 1, tee_node
, 1);
1135 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1137 hr
= IMFTopologyNode_GetOutputCount(src_node
, &count
);
1138 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1139 ok(count
== 2, "Unexpected count %lu.\n", count
);
1141 EXPECT_REF(src_node
, 2);
1142 EXPECT_REF(tee_node
, 2);
1143 hr
= IMFTopologyNode_DisconnectOutput(src_node
, 1);
1144 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1146 ref
= IMFTopologyNode_Release(src_node
);
1147 ok(ref
== 0, "Release returned %ld\n", ref
);
1148 ref
= IMFTopologyNode_Release(tee_node
);
1149 ok(ref
== 0, "Release returned %ld\n", ref
);
1151 ref
= IMFMediaType_Release(mediatype
);
1152 ok(ref
== 0, "Release returned %ld\n", ref
);
1153 ref
= IMFTopology_Release(topology
);
1154 ok(ref
== 0, "Release returned %ld\n", ref
);
1157 static HRESULT WINAPI
test_getservice_QI(IMFGetService
*iface
, REFIID riid
, void **obj
)
1159 if (IsEqualIID(riid
, &IID_IMFGetService
) || IsEqualIID(riid
, &IID_IUnknown
))
1166 return E_NOINTERFACE
;
1169 static ULONG WINAPI
test_getservice_AddRef(IMFGetService
*iface
)
1174 static ULONG WINAPI
test_getservice_Release(IMFGetService
*iface
)
1179 static HRESULT WINAPI
test_getservice_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
1181 *obj
= (void *)0xdeadbeef;
1185 static const IMFGetServiceVtbl testmfgetservicevtbl
=
1188 test_getservice_AddRef
,
1189 test_getservice_Release
,
1190 test_getservice_GetService
,
1193 static IMFGetService test_getservice
= { &testmfgetservicevtbl
};
1195 static HRESULT WINAPI
testservice_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1197 if (IsEqualIID(riid
, &IID_IUnknown
))
1205 if (IsEqualIID(riid
, &IID_IMFGetService
))
1208 return E_NOINTERFACE
;
1211 static HRESULT WINAPI
testservice2_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1213 if (IsEqualIID(riid
, &IID_IUnknown
))
1219 if (IsEqualIID(riid
, &IID_IMFGetService
))
1221 *obj
= &test_getservice
;
1226 return E_NOINTERFACE
;
1229 static ULONG WINAPI
testservice_AddRef(IUnknown
*iface
)
1234 static ULONG WINAPI
testservice_Release(IUnknown
*iface
)
1239 static const IUnknownVtbl testservicevtbl
=
1243 testservice_Release
,
1246 static const IUnknownVtbl testservice2vtbl
=
1250 testservice_Release
,
1253 static IUnknown testservice
= { &testservicevtbl
};
1254 static IUnknown testservice2
= { &testservice2vtbl
};
1256 static void test_MFGetService(void)
1261 hr
= MFGetService(NULL
, NULL
, NULL
, NULL
);
1262 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1264 unk
= (void *)0xdeadbeef;
1265 hr
= MFGetService(NULL
, NULL
, NULL
, (void **)&unk
);
1266 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1267 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1269 hr
= MFGetService(&testservice
, NULL
, NULL
, NULL
);
1270 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1272 unk
= (void *)0xdeadbeef;
1273 hr
= MFGetService(&testservice
, NULL
, NULL
, (void **)&unk
);
1274 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1275 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1278 hr
= MFGetService(&testservice2
, NULL
, NULL
, (void **)&unk
);
1279 ok(hr
== 0x83eddead, "Unexpected return value %#lx.\n", hr
);
1280 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1283 static void test_sequencer_source(void)
1285 IMFSequencerSource
*seq_source
;
1289 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1290 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1292 hr
= MFCreateSequencerSource(NULL
, &seq_source
);
1293 ok(hr
== S_OK
, "Failed to create sequencer source, hr %#lx.\n", hr
);
1295 check_interface(seq_source
, &IID_IMFMediaSourceTopologyProvider
, TRUE
);
1297 ref
= IMFSequencerSource_Release(seq_source
);
1298 ok(ref
== 0, "Release returned %ld\n", ref
);
1301 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1304 struct test_stream_sink
1306 IMFStreamSink IMFStreamSink_iface
;
1307 IMFMediaTypeHandler
*handler
;
1310 static struct test_stream_sink
*impl_from_IMFStreamSink(IMFStreamSink
*iface
)
1312 return CONTAINING_RECORD(iface
, struct test_stream_sink
, IMFStreamSink_iface
);
1315 static HRESULT WINAPI
test_stream_sink_QueryInterface(IMFStreamSink
*iface
, REFIID riid
, void **obj
)
1317 if (IsEqualIID(riid
, &IID_IMFStreamSink
)
1318 || IsEqualIID(riid
, &IID_IMFMediaEventGenerator
)
1319 || IsEqualIID(riid
, &IID_IUnknown
))
1321 IMFStreamSink_AddRef((*obj
= iface
));
1326 return E_NOINTERFACE
;
1329 static ULONG WINAPI
test_stream_sink_AddRef(IMFStreamSink
*iface
)
1334 static ULONG WINAPI
test_stream_sink_Release(IMFStreamSink
*iface
)
1339 static HRESULT WINAPI
test_stream_sink_GetEvent(IMFStreamSink
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1341 ok(0, "Unexpected call.\n");
1345 static HRESULT WINAPI
test_stream_sink_BeginGetEvent(IMFStreamSink
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
1347 ok(0, "Unexpected call.\n");
1351 static HRESULT WINAPI
test_stream_sink_EndGetEvent(IMFStreamSink
*iface
, IMFAsyncResult
*result
,
1352 IMFMediaEvent
**event
)
1354 ok(0, "Unexpected call.\n");
1358 static HRESULT WINAPI
test_stream_sink_QueueEvent(IMFStreamSink
*iface
, MediaEventType event_type
,
1359 REFGUID ext_type
, HRESULT hr
, const PROPVARIANT
*value
)
1361 ok(0, "Unexpected call.\n");
1365 static HRESULT WINAPI
test_stream_sink_GetMediaSink(IMFStreamSink
*iface
, IMFMediaSink
**sink
)
1367 ok(0, "Unexpected call.\n");
1371 static HRESULT WINAPI
test_stream_sink_GetIdentifier(IMFStreamSink
*iface
, DWORD
*id
)
1373 ok(0, "Unexpected call.\n");
1377 static HRESULT WINAPI
test_stream_sink_GetMediaTypeHandler(IMFStreamSink
*iface
, IMFMediaTypeHandler
**handler
)
1379 struct test_stream_sink
*impl
= impl_from_IMFStreamSink(iface
);
1383 IMFMediaTypeHandler_AddRef((*handler
= impl
->handler
));
1387 ok(0, "Unexpected call.\n");
1391 static HRESULT WINAPI
test_stream_sink_ProcessSample(IMFStreamSink
*iface
, IMFSample
*sample
)
1393 ok(0, "Unexpected call.\n");
1397 static HRESULT WINAPI
test_stream_sink_PlaceMarker(IMFStreamSink
*iface
, MFSTREAMSINK_MARKER_TYPE marker_type
,
1398 const PROPVARIANT
*marker_value
, const PROPVARIANT
*context
)
1400 ok(0, "Unexpected call.\n");
1404 static HRESULT WINAPI
test_stream_sink_Flush(IMFStreamSink
*iface
)
1406 ok(0, "Unexpected call.\n");
1410 static const IMFStreamSinkVtbl test_stream_sink_vtbl
=
1412 test_stream_sink_QueryInterface
,
1413 test_stream_sink_AddRef
,
1414 test_stream_sink_Release
,
1415 test_stream_sink_GetEvent
,
1416 test_stream_sink_BeginGetEvent
,
1417 test_stream_sink_EndGetEvent
,
1418 test_stream_sink_QueueEvent
,
1419 test_stream_sink_GetMediaSink
,
1420 test_stream_sink_GetIdentifier
,
1421 test_stream_sink_GetMediaTypeHandler
,
1422 test_stream_sink_ProcessSample
,
1423 test_stream_sink_PlaceMarker
,
1424 test_stream_sink_Flush
,
1427 static const struct test_stream_sink test_stream_sink
= {.IMFStreamSink_iface
.lpVtbl
= &test_stream_sink_vtbl
};
1429 struct test_callback
1431 IMFAsyncCallback IMFAsyncCallback_iface
;
1434 static HRESULT WINAPI
testcallback_QueryInterface(IMFAsyncCallback
*iface
, REFIID riid
, void **obj
)
1436 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
1437 IsEqualIID(riid
, &IID_IUnknown
))
1440 IMFAsyncCallback_AddRef(iface
);
1445 return E_NOINTERFACE
;
1448 static ULONG WINAPI
testcallback_AddRef(IMFAsyncCallback
*iface
)
1453 static ULONG WINAPI
testcallback_Release(IMFAsyncCallback
*iface
)
1458 static HRESULT WINAPI
testcallback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
1460 ok(flags
!= NULL
&& queue
!= NULL
, "Unexpected arguments.\n");
1464 static HRESULT WINAPI
testcallback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1466 ok(result
!= NULL
, "Unexpected result object.\n");
1471 static const IMFAsyncCallbackVtbl testcallbackvtbl
=
1473 testcallback_QueryInterface
,
1474 testcallback_AddRef
,
1475 testcallback_Release
,
1476 testcallback_GetParameters
,
1477 testcallback_Invoke
,
1480 static void init_test_callback(struct test_callback
*callback
)
1482 callback
->IMFAsyncCallback_iface
.lpVtbl
= &testcallbackvtbl
;
1485 static void test_session_events(IMFMediaSession
*session
)
1487 struct test_callback callback
, callback2
;
1488 IMFAsyncResult
*result
;
1489 IMFMediaEvent
*event
;
1492 init_test_callback(&callback
);
1493 init_test_callback(&callback2
);
1495 hr
= IMFMediaSession_GetEvent(session
, MF_EVENT_FLAG_NO_WAIT
, &event
);
1496 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
1499 hr
= IMFMediaSession_BeginGetEvent(session
, NULL
, NULL
);
1500 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1502 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1503 ok(hr
== S_OK
, "Failed to Begin*, hr %#lx.\n", hr
);
1505 /* Same callback, same state. */
1506 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1507 ok(hr
== MF_S_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1509 /* Same callback, different state. */
1510 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1511 ok(hr
== MF_E_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1513 /* Different callback, same state. */
1514 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1515 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1517 /* Different callback, different state. */
1518 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1519 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1521 hr
= MFCreateAsyncResult(NULL
, &callback
.IMFAsyncCallback_iface
, NULL
, &result
);
1522 ok(hr
== S_OK
, "Failed to create result, hr %#lx.\n", hr
);
1524 hr
= IMFMediaSession_EndGetEvent(session
, result
, &event
);
1525 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
1527 /* Shutdown behavior. */
1528 hr
= IMFMediaSession_Shutdown(session
);
1529 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1532 static void test_media_session(void)
1534 IMFRateSupport
*rate_support
;
1535 IMFAttributes
*attributes
;
1536 IMFMediaSession
*session
;
1537 MFSHUTDOWN_STATUS status
;
1538 IMFTopology
*topology
;
1539 IMFShutdown
*shutdown
;
1540 PROPVARIANT propvar
;
1546 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1547 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1549 hr
= MFCreateMediaSession(NULL
, &session
);
1550 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1552 check_interface(session
, &IID_IMFGetService
, TRUE
);
1553 check_interface(session
, &IID_IMFRateSupport
, TRUE
);
1554 check_interface(session
, &IID_IMFRateControl
, TRUE
);
1555 check_interface(session
, &IID_IMFAttributes
, FALSE
);
1556 check_interface(session
, &IID_IMFTopologyNodeAttributeEditor
, FALSE
);
1557 check_interface(session
, &IID_IMFLocalMFTRegistration
, FALSE
);
1558 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
1559 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, TRUE
);
1560 check_service_interface(session
, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE
, &IID_IMFTopologyNodeAttributeEditor
, TRUE
);
1561 check_service_interface(session
, &MF_LOCAL_MFT_REGISTRATION_SERVICE
, &IID_IMFLocalMFTRegistration
, TRUE
);
1563 hr
= IMFMediaSession_GetClock(session
, &clock
);
1564 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1566 hr
= IMFClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
1567 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1569 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1570 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
1572 hr
= IMFMediaSession_Shutdown(session
);
1573 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1575 check_interface(session
, &IID_IMFGetService
, TRUE
);
1577 hr
= IMFMediaSession_QueryInterface(session
, &IID_IMFGetService
, (void **)&gs
);
1578 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1580 hr
= IMFGetService_GetService(gs
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1581 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1583 IMFGetService_Release(gs
);
1585 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1586 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1587 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected shutdown status %u.\n", status
);
1589 IMFShutdown_Release(shutdown
);
1591 hr
= IMFMediaSession_ClearTopologies(session
);
1592 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1594 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, NULL
);
1595 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1597 propvar
.vt
= VT_EMPTY
;
1598 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, &propvar
);
1599 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1601 hr
= IMFMediaSession_Pause(session
);
1602 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1604 hr
= IMFMediaSession_Stop(session
);
1605 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1607 hr
= IMFMediaSession_Close(session
);
1608 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1610 hr
= IMFMediaSession_GetClock(session
, &clock
);
1611 ok(hr
== MF_E_SHUTDOWN
|| broken(hr
== E_UNEXPECTED
) /* Win7 */, "Unexpected hr %#lx.\n", hr
);
1613 hr
= IMFMediaSession_GetSessionCapabilities(session
, &caps
);
1614 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1616 hr
= IMFMediaSession_GetSessionCapabilities(session
, NULL
);
1617 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1619 hr
= IMFMediaSession_GetFullTopology(session
, MFSESSION_GETFULLTOPOLOGY_CURRENT
, 0, &topology
);
1620 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1622 hr
= IMFMediaSession_Shutdown(session
);
1623 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1625 IMFMediaSession_Release(session
);
1627 /* Custom topology loader, GUID is not registered. */
1628 hr
= MFCreateAttributes(&attributes
, 1);
1629 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
1631 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_TOPOLOADER
, &MF_SESSION_TOPOLOADER
);
1632 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1634 hr
= MFCreateMediaSession(attributes
, &session
);
1635 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1636 IMFMediaSession_Release(session
);
1638 /* Disabled quality manager. */
1639 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_QUALITY_MANAGER
, &GUID_NULL
);
1640 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1642 hr
= MFCreateMediaSession(attributes
, &session
);
1643 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1644 IMFMediaSession_Release(session
);
1646 IMFAttributes_Release(attributes
);
1648 /* Basic events behavior. */
1649 hr
= MFCreateMediaSession(NULL
, &session
);
1650 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1652 test_session_events(session
);
1654 IMFMediaSession_Release(session
);
1657 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1660 static void test_media_session_rate_control(void)
1662 IMFRateControl
*rate_control
, *clock_rate_control
;
1663 IMFPresentationClock
*presentation_clock
;
1664 IMFPresentationTimeSource
*time_source
;
1665 MFCLOCK_PROPERTIES clock_props
;
1666 IMFRateSupport
*rate_support
;
1667 IMFMediaSession
*session
;
1673 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1674 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1676 hr
= MFCreateMediaSession(NULL
, &session
);
1677 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1679 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1680 ok(hr
== S_OK
, "Failed to get rate support interface, hr %#lx.\n", hr
);
1682 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, (void **)&rate_control
);
1683 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
1685 hr
= IMFRateControl_GetRate(rate_control
, NULL
, NULL
);
1686 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1689 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
1690 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1691 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1693 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
1694 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1698 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
1699 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1700 ok(!thin
, "Unexpected thinning.\n");
1701 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1703 hr
= IMFMediaSession_GetClock(session
, &clock
);
1704 ok(hr
== S_OK
, "Failed to get clock, hr %#lx.\n", hr
);
1706 hr
= IMFClock_QueryInterface(clock
, &IID_IMFPresentationClock
, (void **)&presentation_clock
);
1707 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1709 hr
= IMFClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&clock_rate_control
);
1710 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1713 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1714 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1715 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1717 hr
= IMFRateControl_SetRate(clock_rate_control
, FALSE
, 1.5f
);
1718 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1720 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1721 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1723 hr
= IMFClock_GetProperties(clock
, &clock_props
);
1724 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1726 hr
= MFCreateSystemTimeSource(&time_source
);
1727 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
1729 hr
= IMFPresentationClock_SetTimeSource(presentation_clock
, time_source
);
1730 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
1732 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1733 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1736 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1737 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1738 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1740 IMFPresentationTimeSource_Release(time_source
);
1742 IMFRateControl_Release(clock_rate_control
);
1743 IMFPresentationClock_Release(presentation_clock
);
1744 IMFClock_Release(clock
);
1746 IMFRateControl_Release(rate_control
);
1747 IMFRateSupport_Release(rate_support
);
1749 IMFMediaSession_Release(session
);
1752 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1755 static HRESULT WINAPI
test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
,
1758 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
1759 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
1760 IsEqualIID(riid
, &IID_IUnknown
))
1763 IMFSampleGrabberSinkCallback_AddRef(iface
);
1768 return E_NOINTERFACE
;
1771 static ULONG WINAPI
test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
1776 static ULONG WINAPI
test_grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
1781 static HRESULT WINAPI
test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
,
1787 static HRESULT WINAPI
test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1792 static HRESULT WINAPI
test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1797 static HRESULT WINAPI
test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1802 static HRESULT WINAPI
test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
, float rate
)
1807 static HRESULT WINAPI
test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
1808 IMFPresentationClock
*clock
)
1813 static HRESULT WINAPI
test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
1814 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
1819 static HRESULT WINAPI
test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
1824 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl
=
1826 test_grabber_callback_QueryInterface
,
1827 test_grabber_callback_AddRef
,
1828 test_grabber_callback_Release
,
1829 test_grabber_callback_OnClockStart
,
1830 test_grabber_callback_OnClockStop
,
1831 test_grabber_callback_OnClockPause
,
1832 test_grabber_callback_OnClockRestart
,
1833 test_grabber_callback_OnClockSetRate
,
1834 test_grabber_callback_OnSetPresentationClock
,
1835 test_grabber_callback_OnProcessSample
,
1836 test_grabber_callback_OnShutdown
,
1841 IMFMediaSource IMFMediaSource_iface
;
1845 static struct test_source
*impl_from_IMFMediaSource(IMFMediaSource
*iface
)
1847 return CONTAINING_RECORD(iface
, struct test_source
, IMFMediaSource_iface
);
1850 static HRESULT WINAPI
test_source_QueryInterface(IMFMediaSource
*iface
, REFIID riid
, void **out
)
1852 if (IsEqualIID(riid
, &IID_IMFMediaSource
)
1853 || IsEqualIID(riid
, &IID_IMFMediaEventGenerator
)
1854 || IsEqualIID(riid
, &IID_IUnknown
))
1861 return E_NOINTERFACE
;
1864 IMFMediaSource_AddRef(iface
);
1868 static ULONG WINAPI
test_source_AddRef(IMFMediaSource
*iface
)
1870 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1871 return InterlockedIncrement(&source
->refcount
);
1874 static ULONG WINAPI
test_source_Release(IMFMediaSource
*iface
)
1876 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1877 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
1885 static HRESULT WINAPI
test_source_GetEvent(IMFMediaSource
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1887 ok(0, "Unexpected call.\n");
1891 static HRESULT WINAPI
test_source_BeginGetEvent(IMFMediaSource
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
1893 ok(0, "Unexpected call.\n");
1897 static HRESULT WINAPI
test_source_EndGetEvent(IMFMediaSource
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
1899 ok(0, "Unexpected call.\n");
1903 static HRESULT WINAPI
test_source_QueueEvent(IMFMediaSource
*iface
, MediaEventType event_type
, REFGUID ext_type
,
1904 HRESULT hr
, const PROPVARIANT
*value
)
1906 ok(0, "Unexpected call.\n");
1910 static HRESULT WINAPI
test_source_GetCharacteristics(IMFMediaSource
*iface
, DWORD
*flags
)
1912 ok(0, "Unexpected call.\n");
1916 static HRESULT WINAPI
test_source_CreatePresentationDescriptor(IMFMediaSource
*iface
, IMFPresentationDescriptor
**pd
)
1918 ok(0, "Unexpected call.\n");
1922 static HRESULT WINAPI
test_source_Start(IMFMediaSource
*iface
, IMFPresentationDescriptor
*pd
, const GUID
*time_format
,
1923 const PROPVARIANT
*start_position
)
1925 ok(0, "Unexpected call.\n");
1929 static HRESULT WINAPI
test_source_Stop(IMFMediaSource
*iface
)
1931 ok(0, "Unexpected call.\n");
1935 static HRESULT WINAPI
test_source_Pause(IMFMediaSource
*iface
)
1937 ok(0, "Unexpected call.\n");
1941 static HRESULT WINAPI
test_source_Shutdown(IMFMediaSource
*iface
)
1943 ok(0, "Unexpected call.\n");
1947 static const IMFMediaSourceVtbl test_source_vtbl
=
1949 test_source_QueryInterface
,
1951 test_source_Release
,
1952 test_source_GetEvent
,
1953 test_source_BeginGetEvent
,
1954 test_source_EndGetEvent
,
1955 test_source_QueueEvent
,
1956 test_source_GetCharacteristics
,
1957 test_source_CreatePresentationDescriptor
,
1961 test_source_Shutdown
,
1964 static IMFMediaSource
*create_test_source(void)
1966 struct test_source
*source
;
1968 source
= calloc(1, sizeof(*source
));
1969 source
->IMFMediaSource_iface
.lpVtbl
= &test_source_vtbl
;
1970 source
->refcount
= 1;
1972 return &source
->IMFMediaSource_iface
;
1975 static void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
1980 hr
= IMFMediaType_DeleteAllItems(mediatype
);
1981 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1983 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
1985 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
1986 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
1990 static void init_source_node(IMFMediaSource
*source
, IMFTopologyNode
*node
,
1991 UINT enum_types_count
, IMFMediaType
**enum_types
, const media_type_desc
*current_desc
)
1993 IMFPresentationDescriptor
*pd
;
1994 IMFStreamDescriptor
*sd
;
1997 hr
= IMFTopologyNode_DeleteAllItems(node
);
1998 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2000 hr
= MFCreateStreamDescriptor(0, enum_types_count
, enum_types
, &sd
);
2001 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
2003 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
2004 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
2006 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
2007 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
2009 IMFPresentationDescriptor_Release(pd
);
2011 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
2012 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
2016 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
2017 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2022 IMFMediaTypeHandler
*handler
;
2025 hr
= MFCreateMediaType(&type
);
2026 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2027 init_media_type(type
, *current_desc
, -1);
2029 hr
= IMFStreamDescriptor_GetMediaTypeHandler(sd
, &handler
);
2030 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2031 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, type
);
2032 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2034 IMFMediaTypeHandler_Release(handler
);
2035 IMFMediaType_Release(type
);
2038 IMFStreamDescriptor_Release(sd
);
2041 static void init_sink_node(IMFActivate
*sink_activate
, MF_CONNECT_METHOD method
, IMFTopologyNode
*node
)
2043 IMFStreamSink
*stream_sink
;
2047 hr
= IMFTopologyNode_DeleteAllItems(node
);
2048 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2050 hr
= IMFActivate_ActivateObject(sink_activate
, &IID_IMFMediaSink
, (void **)&sink
);
2051 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
2053 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
2054 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2056 IMFMediaSink_Release(sink
);
2058 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)stream_sink
);
2059 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
2061 IMFStreamSink_Release(stream_sink
);
2063 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_CONNECT_METHOD
, method
);
2064 ok(hr
== S_OK
, "Failed to set connect method, hr %#lx.\n", hr
);
2067 enum loader_test_flags
2069 LOADER_EXPECTED_DECODER
= 0x1,
2070 LOADER_EXPECTED_CONVERTER
= 0x2,
2072 LOADER_NEEDS_VIDEO_PROCESSOR
= 0x8,
2073 LOADER_SET_ENUMERATE_SOURCE_TYPES
= 0x10,
2076 static void test_topology_loader(void)
2078 static const media_type_desc audio_pcm_44100
=
2080 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2081 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2082 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2083 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2084 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
2085 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2086 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2088 static const media_type_desc audio_pcm_48000
=
2090 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2091 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2092 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2093 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
2094 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000),
2095 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2096 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2098 static const media_type_desc audio_mp3_44100
=
2100 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2101 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
2102 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2103 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2104 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
2105 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2107 static const media_type_desc audio_pcm_44100_incomplete
=
2109 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2110 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2111 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2112 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2113 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2114 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2117 const struct loader_test
2119 const media_type_desc
*input_type
;
2120 const media_type_desc
*output_type
;
2121 const media_type_desc
*current_input
;
2122 MF_CONNECT_METHOD method
;
2123 HRESULT expected_result
;
2129 /* PCM -> PCM, same enumerated type, no current type */
2130 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2131 .expected_result
= S_OK
,
2132 .flags
= LOADER_TODO
,
2135 /* PCM -> PCM, same enumerated type, incomplete current type */
2136 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2137 .current_input
= &audio_pcm_44100_incomplete
,
2138 .expected_result
= MF_E_INVALIDMEDIATYPE
,
2139 .flags
= LOADER_TODO
,
2142 /* PCM -> PCM, same enumerated bps, different current bps */
2143 .input_type
= &audio_pcm_48000
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_DIRECT
,
2144 .current_input
= &audio_pcm_44100
,
2145 .expected_result
= MF_E_INVALIDMEDIATYPE
,
2148 /* PCM -> PCM, same enumerated bps, different current bps, force enumerate */
2149 .input_type
= &audio_pcm_48000
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_DIRECT
,
2150 .current_input
= &audio_pcm_44100
,
2151 .expected_result
= S_OK
,
2152 .flags
= LOADER_SET_ENUMERATE_SOURCE_TYPES
,
2156 /* PCM -> PCM, incomplete enumerated type, same current type */
2157 .input_type
= &audio_pcm_44100_incomplete
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2158 .current_input
= &audio_pcm_44100
,
2159 .expected_result
= S_OK
,
2162 /* PCM -> PCM, incomplete enumerated type, same current type, force enumerate */
2163 .input_type
= &audio_pcm_44100_incomplete
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2164 .current_input
= &audio_pcm_44100
,
2165 .expected_result
= MF_E_NO_MORE_TYPES
,
2166 .flags
= LOADER_SET_ENUMERATE_SOURCE_TYPES
| LOADER_TODO
,
2170 /* PCM -> PCM, different enumerated bps, no current type */
2171 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_DIRECT
,
2172 .expected_result
= MF_E_INVALIDMEDIATYPE
,
2173 .flags
= LOADER_TODO
,
2176 /* PCM -> PCM, different enumerated bps, same current bps */
2177 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_DIRECT
,
2178 .current_input
= &audio_pcm_48000
,
2179 .expected_result
= S_OK
,
2182 /* PCM -> PCM, different enumerated bps, same current bps, force enumerate */
2183 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_DIRECT
,
2184 .current_input
= &audio_pcm_48000
,
2185 .expected_result
= MF_E_NO_MORE_TYPES
,
2186 .flags
= LOADER_SET_ENUMERATE_SOURCE_TYPES
,
2189 /* PCM -> PCM, different enumerated bps, no current type, allow converter */
2190 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_ALLOW_CONVERTER
,
2191 .expected_result
= S_OK
,
2192 .flags
= LOADER_NEEDS_VIDEO_PROCESSOR
| LOADER_EXPECTED_CONVERTER
| LOADER_TODO
,
2195 /* PCM -> PCM, different enumerated bps, no current type, allow decoder */
2196 .input_type
= &audio_pcm_44100
, .output_type
= &audio_pcm_48000
, .method
= MF_CONNECT_ALLOW_DECODER
,
2197 .expected_result
= S_OK
,
2198 .flags
= LOADER_NEEDS_VIDEO_PROCESSOR
| LOADER_EXPECTED_CONVERTER
| LOADER_TODO
,
2203 .input_type
= &audio_mp3_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2204 .current_input
= &audio_mp3_44100
,
2205 .expected_result
= MF_E_INVALIDMEDIATYPE
,
2208 /* MP3 -> PCM, force enumerate */
2209 .input_type
= &audio_mp3_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_DIRECT
,
2210 .current_input
= &audio_mp3_44100
,
2211 .expected_result
= MF_E_NO_MORE_TYPES
,
2212 .flags
= LOADER_SET_ENUMERATE_SOURCE_TYPES
,
2216 .input_type
= &audio_mp3_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_ALLOW_CONVERTER
,
2217 .current_input
= &audio_mp3_44100
,
2218 .expected_result
= MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION
,
2219 .flags
= LOADER_NEEDS_VIDEO_PROCESSOR
| LOADER_TODO
,
2223 .input_type
= &audio_mp3_44100
, .output_type
= &audio_pcm_44100
, .method
= MF_CONNECT_ALLOW_DECODER
,
2224 .current_input
= &audio_mp3_44100
,
2225 .expected_result
= S_OK
,
2226 .flags
= LOADER_EXPECTED_DECODER
| LOADER_TODO
,
2230 IMFSampleGrabberSinkCallback test_grabber_callback
= { &test_grabber_callback_vtbl
};
2231 IMFTopologyNode
*src_node
, *sink_node
, *src_node2
, *sink_node2
, *mft_node
;
2232 IMFTopology
*topology
, *topology2
, *full_topology
;
2233 IMFMediaType
*media_type
, *input_type
, *output_type
;
2234 IMFPresentationDescriptor
*pd
;
2235 unsigned int i
, count
, value
;
2236 IMFActivate
*sink_activate
;
2237 MF_TOPOLOGY_TYPE node_type
;
2238 IMFStreamDescriptor
*sd
;
2239 IMFTransform
*transform
;
2240 IMFMediaSource
*source
;
2241 IMFTopoLoader
*loader
;
2242 IUnknown
*node_object
;
2250 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2251 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
2253 hr
= MFCreateTopoLoader(NULL
);
2254 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2256 hr
= MFCreateTopoLoader(&loader
);
2257 ok(hr
== S_OK
, "Failed to create topology loader, hr %#lx.\n", hr
);
2259 hr
= MFCreateTopology(&topology
);
2260 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
2262 /* Empty topology */
2263 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2264 todo_wine_if(hr
== S_OK
)
2265 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2266 if (hr
== S_OK
) IMFTopology_Release(full_topology
);
2268 /* Add source node. */
2269 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
2270 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2272 /* When a decoder is involved, windows requires this attribute to be present */
2273 source
= create_test_source();
2275 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
2276 ok(hr
== S_OK
, "Failed to set node source, hr %#lx.\n", hr
);
2278 hr
= MFCreateMediaType(&media_type
);
2279 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2281 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2282 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2283 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2284 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2286 hr
= MFCreateStreamDescriptor(0, 1, &media_type
, &sd
);
2287 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
2289 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
2290 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
2292 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
2293 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
2295 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
2296 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
2298 IMFMediaType_Release(media_type
);
2300 hr
= IMFTopology_AddNode(topology
, src_node
);
2301 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
2303 /* Source node only. */
2304 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2305 todo_wine_if(hr
== E_INVALIDARG
)
2306 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2308 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &sink_node
);
2309 ok(hr
== S_OK
, "Failed to create output node, hr %#lx.\n", hr
);
2311 hr
= MFCreateMediaType(&media_type
);
2312 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2314 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2315 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2316 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2317 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2319 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &test_grabber_callback
, &sink_activate
);
2320 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2322 hr
= IMFTopologyNode_SetObject(sink_node
, (IUnknown
*)sink_activate
);
2323 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
2325 IMFMediaType_Release(media_type
);
2327 hr
= IMFTopology_AddNode(topology
, sink_node
);
2328 ok(hr
== S_OK
, "Failed to add sink node, hr %#lx.\n", hr
);
2330 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2331 todo_wine_if(hr
== MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
)
2332 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2334 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, sink_node
, 0);
2335 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
2337 /* Sink was not resolved. */
2338 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2339 ok(hr
== MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2341 hr
= MFCreateMediaType(&input_type
);
2342 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2344 hr
= MFCreateMediaType(&output_type
);
2345 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2347 for (i
= 0; i
< ARRAY_SIZE(loader_tests
); ++i
)
2349 const struct loader_test
*test
= &loader_tests
[i
];
2351 winetest_push_context("%u", i
);
2353 init_media_type(input_type
, *test
->input_type
, -1);
2354 init_media_type(output_type
, *test
->output_type
, -1);
2356 hr
= MFCreateSampleGrabberSinkActivate(output_type
, &test_grabber_callback
, &sink_activate
);
2357 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2359 init_source_node(source
, src_node
, 1, &input_type
, test
->current_input
);
2360 init_sink_node(sink_activate
, test
->method
, sink_node
);
2362 hr
= IMFTopology_GetCount(topology
, &count
);
2363 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2364 ok(!count
, "Unexpected count %u.\n", count
);
2366 if (test
->flags
& LOADER_SET_ENUMERATE_SOURCE_TYPES
)
2367 IMFTopology_SetUINT32(topology
, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
, 1);
2368 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2369 IMFTopology_DeleteItem(topology
, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES
);
2371 if (test
->flags
& LOADER_NEEDS_VIDEO_PROCESSOR
&& !has_video_processor
)
2372 ok(hr
== MF_E_INVALIDMEDIATYPE
|| hr
== MF_E_TOPO_CODEC_NOT_FOUND
,
2373 "Unexpected hr %#lx\n", hr
);
2376 todo_wine_if(test
->flags
& LOADER_TODO
)
2377 ok(hr
== test
->expected_result
, "Unexpected hr %#lx\n", hr
);
2378 ok(full_topology
!= topology
, "Unexpected instance.\n");
2381 if (test
->expected_result
!= hr
)
2383 if (hr
!= S_OK
) ref
= 0;
2384 else ref
= IMFTopology_Release(full_topology
);
2385 ok(ref
== 0, "Release returned %ld\n", ref
);
2387 else if (test
->expected_result
== S_OK
)
2389 hr
= IMFTopology_GetCount(full_topology
, &count
);
2390 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2392 ok(count
== (test
->flags
& LOADER_SET_ENUMERATE_SOURCE_TYPES
? 2 : 1),
2393 "Unexpected count %u.\n", count
);
2396 hr
= IMFTopology_GetUINT32(full_topology
, &MF_TOPOLOGY_RESOLUTION_STATUS
, &value
);
2398 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2399 ok(value
== MF_TOPOLOGY_RESOLUTION_SUCCEEDED
, "Unexpected value %#x.\n", value
);
2402 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2404 if (test
->flags
& LOADER_EXPECTED_CONVERTER
)
2407 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2408 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
2409 todo_wine_if(test
->flags
& (LOADER_EXPECTED_CONVERTER
| LOADER_EXPECTED_DECODER
))
2410 ok(node_count
== count
, "Unexpected node count %u.\n", node_count
);
2412 hr
= IMFTopologyNode_GetTopoNodeID(src_node
, &node_id
);
2413 ok(hr
== S_OK
, "Failed to get source node id, hr %#lx.\n", hr
);
2415 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &src_node2
);
2416 ok(hr
== S_OK
, "Failed to get source in resolved topology, hr %#lx.\n", hr
);
2418 hr
= IMFTopologyNode_GetTopoNodeID(sink_node
, &node_id
);
2419 ok(hr
== S_OK
, "Failed to get sink node id, hr %#lx.\n", hr
);
2421 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &sink_node2
);
2422 ok(hr
== S_OK
, "Failed to get sink in resolved topology, hr %#lx.\n", hr
);
2424 if (test
->flags
& (LOADER_EXPECTED_DECODER
| LOADER_EXPECTED_CONVERTER
) && strcmp(winetest_platform
, "wine"))
2426 hr
= IMFTopologyNode_GetOutput(src_node2
, 0, &mft_node
, &index
);
2427 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2428 ok(!index
, "Unexpected stream index %lu.\n", index
);
2430 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2431 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2432 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2434 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2435 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2437 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2440 hr
= IMFTopologyNode_GetUINT32(mft_node
, &MF_TOPONODE_DECODER
, &value
);
2441 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2442 ok(value
== 1, "Unexpected value.\n");
2445 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2446 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2448 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void **)&transform
);
2449 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2450 IUnknown_Release(node_object
);
2452 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
2453 ok(hr
== S_OK
, "Failed to get transform input type, hr %#lx.\n", hr
);
2455 hr
= IMFMediaType_Compare(input_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2456 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2457 ok(ret
, "Input type of first transform doesn't match source node type.\n");
2459 IMFTopologyNode_Release(mft_node
);
2460 IMFMediaType_Release(media_type
);
2461 IMFTransform_Release(transform
);
2463 hr
= IMFTopologyNode_GetInput(sink_node2
, 0, &mft_node
, &index
);
2464 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2465 ok(!index
, "Unexpected stream index %lu.\n", index
);
2467 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2468 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2469 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2471 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2472 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2474 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2475 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2477 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void**) &transform
);
2478 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2479 IUnknown_Release(node_object
);
2481 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
2482 ok(hr
== S_OK
, "Failed to get transform output type, hr %#lx.\n", hr
);
2484 hr
= IMFMediaType_Compare(output_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2485 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2486 ok(ret
, "Output type of last transform doesn't match sink node type.\n");
2488 IMFTopologyNode_Release(mft_node
);
2489 IMFMediaType_Release(media_type
);
2490 IMFTransform_Release(transform
);
2493 IMFTopologyNode_Release(src_node2
);
2494 IMFTopologyNode_Release(sink_node2
);
2496 hr
= IMFTopology_SetUINT32(full_topology
, &IID_IMFTopology
, 123);
2497 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2498 hr
= IMFTopoLoader_Load(loader
, full_topology
, &topology2
, NULL
);
2499 ok(hr
== S_OK
, "Failed to resolve topology, hr %#lx.\n", hr
);
2500 ok(full_topology
!= topology2
, "Unexpected instance.\n");
2501 hr
= IMFTopology_GetUINT32(topology2
, &IID_IMFTopology
, &value
);
2502 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2504 ref
= IMFTopology_Release(topology2
);
2505 ok(ref
== 0, "Release returned %ld\n", ref
);
2506 ref
= IMFTopology_Release(full_topology
);
2507 ok(ref
== 0, "Release returned %ld\n", ref
);
2510 hr
= IMFTopology_GetCount(topology
, &count
);
2511 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2512 ok(!count
, "Unexpected count %u.\n", count
);
2514 hr
= IMFActivate_ShutdownObject(sink_activate
);
2515 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2516 ref
= IMFActivate_Release(sink_activate
);
2517 ok(ref
== 0, "Release returned %ld\n", ref
);
2519 winetest_pop_context();
2522 ref
= IMFTopology_Release(topology
);
2523 ok(ref
== 0, "Release returned %ld\n", ref
);
2524 ref
= IMFTopoLoader_Release(loader
);
2525 ok(ref
== 0, "Release returned %ld\n", ref
);
2526 ref
= IMFTopologyNode_Release(src_node
);
2527 ok(ref
== 0, "Release returned %ld\n", ref
);
2528 ref
= IMFTopologyNode_Release(sink_node
);
2529 ok(ref
== 0, "Release returned %ld\n", ref
);
2531 ref
= IMFMediaSource_Release(source
);
2532 ok(ref
== 0, "Release returned %ld\n", ref
);
2534 ref
= IMFPresentationDescriptor_Release(pd
);
2535 ok(ref
== 0, "Release returned %ld\n", ref
);
2536 ref
= IMFStreamDescriptor_Release(sd
);
2537 ok(ref
== 0, "Release returned %ld\n", ref
);
2539 ref
= IMFMediaType_Release(input_type
);
2540 ok(ref
== 0, "Release returned %ld\n", ref
);
2541 /* FIXME: is native really leaking refs here, or are we? */
2542 ref
= IMFMediaType_Release(output_type
);
2544 ok(ref
!= 0, "Release returned %ld\n", ref
);
2547 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
2550 static void test_topology_loader_evr(void)
2552 static const media_type_desc media_type_desc
=
2554 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2555 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
2556 ATTR_RATIO(MF_MT_FRAME_SIZE
, 640, 480),
2557 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
),
2560 IMFTopologyNode
*node
, *source_node
, *evr_node
;
2561 IMFTopology
*topology
, *full_topology
;
2562 IMFMediaTypeHandler
*handler
;
2563 unsigned int i
, count
, value
;
2564 IMFStreamSink
*stream_sink
;
2565 IMFMediaType
*media_type
;
2566 IMFActivate
*activate
;
2567 IMFTopoLoader
*loader
;
2575 hr
= CoInitialize(NULL
);
2576 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2578 hr
= MFCreateTopoLoader(&loader
);
2579 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2582 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &source_node
);
2583 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2585 hr
= MFCreateMediaType(&media_type
);
2586 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2587 init_media_type(media_type
, media_type_desc
, -1);
2588 init_source_node(NULL
, source_node
, 1, &media_type
, &media_type_desc
);
2590 /* EVR sink node. */
2591 window
= create_window();
2593 hr
= MFCreateVideoRendererActivate(window
, &activate
);
2594 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
2596 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2597 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2599 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
2600 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2602 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &evr_node
);
2603 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2605 hr
= IMFTopologyNode_SetObject(evr_node
, (IUnknown
*)stream_sink
);
2606 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2608 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
2609 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2610 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
2611 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2612 IMFMediaTypeHandler_Release(handler
);
2614 IMFStreamSink_Release(stream_sink
);
2616 hr
= MFCreateTopology(&topology
);
2617 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2619 hr
= IMFTopology_AddNode(topology
, source_node
);
2620 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2621 hr
= IMFTopology_AddNode(topology
, evr_node
);
2622 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2623 hr
= IMFTopologyNode_ConnectOutput(source_node
, 0, evr_node
, 0);
2624 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2626 hr
= IMFTopologyNode_SetUINT32(evr_node
, &MF_TOPONODE_CONNECT_METHOD
, MF_CONNECT_DIRECT
);
2627 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2629 hr
= IMFTopologyNode_GetCount(evr_node
, &count
);
2630 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2631 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
2633 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2634 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2636 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2637 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2638 ok(node_count
== 3, "Unexpected node count %u.\n", node_count
);
2640 for (i
= 0; i
< node_count
; ++i
)
2642 MF_TOPOLOGY_TYPE node_type
;
2644 hr
= IMFTopology_GetNode(full_topology
, i
, &node
);
2645 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2647 hr
= IMFTopologyNode_GetNodeType(node
, &node_type
);
2648 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2650 if (node_type
== MF_TOPOLOGY_OUTPUT_NODE
)
2653 hr
= IMFTopologyNode_GetUINT32(node
, &MF_TOPONODE_STREAMID
, &value
);
2654 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2655 ok(!value
, "Unexpected stream id %u.\n", value
);
2657 else if (node_type
== MF_TOPOLOGY_SOURCESTREAM_NODE
)
2660 hr
= IMFTopologyNode_GetUINT64(node
, &MF_TOPONODE_MEDIASTART
, &value64
);
2661 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2662 ok(!value64
, "Unexpected value.\n");
2665 IMFTopologyNode_Release(node
);
2668 ref
= IMFTopology_Release(full_topology
);
2669 ok(ref
== 0, "Release returned %ld\n", ref
);
2670 ref
= IMFTopoLoader_Release(loader
);
2671 ok(ref
== 0, "Release returned %ld\n", ref
);
2672 ref
= IMFTopology_Release(topology
);
2673 ok(ref
== 0, "Release returned %ld\n", ref
);
2674 ref
= IMFTopologyNode_Release(source_node
);
2675 ok(ref
== 0, "Release returned %ld\n", ref
);
2676 ref
= IMFTopologyNode_Release(evr_node
);
2677 ok(ref
== 0, "Release returned %ld\n", ref
);
2679 hr
= IMFActivate_ShutdownObject(activate
);
2680 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2681 ref
= IMFActivate_Release(activate
);
2682 ok(ref
== 0, "Release returned %ld\n", ref
);
2683 ref
= IMFMediaSink_Release(sink
);
2684 ok(ref
== 0, "Release returned %ld\n", ref
);
2686 ref
= IMFMediaType_Release(media_type
);
2687 ok(ref
== 0, "Release returned %ld\n", ref
);
2689 DestroyWindow(window
);
2694 static HRESULT WINAPI
testshutdown_QueryInterface(IMFShutdown
*iface
, REFIID riid
, void **obj
)
2696 if (IsEqualIID(riid
, &IID_IMFShutdown
) ||
2697 IsEqualIID(riid
, &IID_IUnknown
))
2700 IMFShutdown_AddRef(iface
);
2705 return E_NOINTERFACE
;
2708 static ULONG WINAPI
testshutdown_AddRef(IMFShutdown
*iface
)
2713 static ULONG WINAPI
testshutdown_Release(IMFShutdown
*iface
)
2718 static HRESULT WINAPI
testshutdown_Shutdown(IMFShutdown
*iface
)
2723 static HRESULT WINAPI
testshutdown_GetShutdownStatus(IMFShutdown
*iface
, MFSHUTDOWN_STATUS
*status
)
2725 ok(0, "Unexpected call.\n");
2729 static const IMFShutdownVtbl testshutdownvtbl
=
2731 testshutdown_QueryInterface
,
2732 testshutdown_AddRef
,
2733 testshutdown_Release
,
2734 testshutdown_Shutdown
,
2735 testshutdown_GetShutdownStatus
,
2738 static void test_MFShutdownObject(void)
2740 IMFShutdown testshutdown
= { &testshutdownvtbl
};
2741 IUnknown testshutdown2
= { &testservicevtbl
};
2744 hr
= MFShutdownObject(NULL
);
2745 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2747 hr
= MFShutdownObject((IUnknown
*)&testshutdown
);
2748 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2750 hr
= MFShutdownObject(&testshutdown2
);
2751 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2761 static HRESULT WINAPI
test_clock_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **obj
)
2763 if (IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2764 IsEqualIID(riid
, &IID_IUnknown
))
2767 IMFClockStateSink_AddRef(iface
);
2772 return E_NOINTERFACE
;
2775 static ULONG WINAPI
test_clock_sink_AddRef(IMFClockStateSink
*iface
)
2780 static ULONG WINAPI
test_clock_sink_Release(IMFClockStateSink
*iface
)
2785 static HRESULT WINAPI
test_clock_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
, LONGLONG offset
)
2790 static HRESULT WINAPI
test_clock_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
2795 static HRESULT WINAPI
test_clock_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
2800 static HRESULT WINAPI
test_clock_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
2805 static HRESULT WINAPI
test_clock_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
2810 static const IMFClockStateSinkVtbl test_clock_sink_vtbl
=
2812 test_clock_sink_QueryInterface
,
2813 test_clock_sink_AddRef
,
2814 test_clock_sink_Release
,
2815 test_clock_sink_OnClockStart
,
2816 test_clock_sink_OnClockStop
,
2817 test_clock_sink_OnClockPause
,
2818 test_clock_sink_OnClockRestart
,
2819 test_clock_sink_OnClockSetRate
,
2822 static void test_presentation_clock(void)
2824 static const struct clock_state_test
2826 enum clock_action action
;
2827 MFCLOCK_STATE clock_state
;
2828 MFCLOCK_STATE source_state
;
2831 clock_state_change
[] =
2833 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
},
2834 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_INVALIDREQUEST
},
2835 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_CLOCK_STATE_ALREADY_SET
},
2836 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2837 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2838 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2839 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2840 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2841 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2842 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2843 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2844 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_INVALIDREQUEST
},
2845 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2846 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2847 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2849 IMFClockStateSink test_sink
= { &test_clock_sink_vtbl
};
2850 IMFPresentationTimeSource
*time_source
;
2851 MFCLOCK_PROPERTIES props
, props2
;
2852 IMFRateControl
*rate_control
;
2853 IMFPresentationClock
*clock
;
2854 MFSHUTDOWN_STATUS status
;
2855 IMFShutdown
*shutdown
;
2856 MFTIME systime
, time
;
2857 LONGLONG clock_time
;
2858 MFCLOCK_STATE state
;
2865 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2866 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
2868 hr
= MFCreatePresentationClock(&clock
);
2869 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
2871 check_interface(clock
, &IID_IMFTimer
, TRUE
);
2872 check_interface(clock
, &IID_IMFRateControl
, TRUE
);
2873 check_interface(clock
, &IID_IMFPresentationClock
, TRUE
);
2874 check_interface(clock
, &IID_IMFShutdown
, TRUE
);
2875 check_interface(clock
, &IID_IMFClock
, TRUE
);
2877 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&rate_control
);
2878 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
2880 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2881 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2883 hr
= IMFPresentationClock_GetTimeSource(clock
, NULL
);
2884 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2886 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2887 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2889 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, NULL
);
2890 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2892 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2893 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2895 hr
= IMFPresentationClock_GetTime(clock
, NULL
);
2896 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2899 hr
= IMFPresentationClock_GetContinuityKey(clock
, &value
);
2900 ok(hr
== S_OK
, "Failed to get continuity key, hr %#lx.\n", hr
);
2901 ok(value
== 0, "Unexpected value %lu.\n", value
);
2903 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2904 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2906 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2907 ok(hr
== S_OK
, "Failed to get state, hr %#lx.\n", hr
);
2908 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2910 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &clock_time
, &systime
);
2911 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2913 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, NULL
, &systime
);
2914 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2916 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, NULL
);
2917 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2920 hr
= IMFPresentationClock_AddClockStateSink(clock
, NULL
);
2921 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2923 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2924 ok(hr
== S_OK
, "Failed to add a sink, hr %#lx.\n", hr
);
2926 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2927 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2929 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, NULL
);
2930 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2932 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2933 ok(hr
== S_OK
, "Failed to remove sink, hr %#lx.\n", hr
);
2935 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2936 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2938 /* State change commands, time source is not set yet. */
2939 hr
= IMFPresentationClock_Start(clock
, 0);
2940 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2942 hr
= IMFPresentationClock_Pause(clock
);
2943 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2945 hr
= IMFPresentationClock_Stop(clock
);
2946 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2948 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2949 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2951 /* Set default time source. */
2952 hr
= MFCreateSystemTimeSource(&time_source
);
2953 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
2955 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &value
);
2956 ok(hr
== S_OK
, "Failed to get time source flags, hr %#lx.\n", hr
);
2957 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2958 "Unexpected clock flags %#lx.\n", value
);
2960 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
2961 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
2963 hr
= IMFPresentationTimeSource_GetProperties(time_source
, &props2
);
2964 ok(hr
== S_OK
, "Failed to get time source properties, hr %#lx.\n", hr
);
2966 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2967 ok(hr
== S_OK
, "Failed to get clock flags, hr %#lx.\n", hr
);
2968 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2969 "Unexpected clock flags %#lx.\n", value
);
2971 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2972 ok(hr
== S_OK
, "Failed to get clock properties, hr %#lx.\n", hr
);
2973 ok(!memcmp(&props
, &props2
, sizeof(props
)), "Unexpected clock properties.\n");
2975 /* Changing rate at initial state. */
2976 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2977 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2978 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2980 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2981 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2982 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2983 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2984 ok(rate
== 0.0f
, "Unexpected rate.\n");
2985 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2986 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2988 /* State changes. */
2989 for (i
= 0; i
< ARRAY_SIZE(clock_state_change
); ++i
)
2991 switch (clock_state_change
[i
].action
)
2994 hr
= IMFPresentationClock_Stop(clock
);
2997 hr
= IMFPresentationClock_Pause(clock
);
3000 hr
= IMFPresentationClock_Start(clock
, 0);
3005 ok(hr
== clock_state_change
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
3007 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
3008 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
3009 ok(state
== clock_state_change
[i
].source_state
, "%u: unexpected state %d.\n", i
, state
);
3011 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
3012 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
3013 ok(state
== clock_state_change
[i
].clock_state
, "%u: unexpected state %d.\n", i
, state
);
3016 /* Clock time stamps. */
3017 hr
= IMFPresentationClock_Start(clock
, 10);
3018 ok(hr
== S_OK
, "Failed to start presentation clock, hr %#lx.\n", hr
);
3020 hr
= IMFPresentationClock_Pause(clock
);
3021 ok(hr
== S_OK
, "Failed to pause presentation clock, hr %#lx.\n", hr
);
3023 hr
= IMFPresentationClock_GetTime(clock
, &time
);
3024 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
3026 hr
= IMFPresentationTimeSource_GetCorrelatedTime(time_source
, 0, &clock_time
, &systime
);
3027 ok(hr
== S_OK
, "Failed to get time source time, hr %#lx.\n", hr
);
3028 ok(time
== clock_time
, "Unexpected clock time.\n");
3030 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, &systime
);
3031 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
3032 ok(time
== clock_time
, "Unexpected clock time.\n");
3034 IMFPresentationTimeSource_Release(time_source
);
3036 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
3037 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
3039 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
3040 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3042 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
3043 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
3044 ok(rate
== 1.0f
, "Unexpected rate.\n");
3045 ok(!thin
, "Unexpected thinning.\n");
3047 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
3048 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
3049 ok(state
== MFCLOCK_STATE_PAUSED
, "Unexpected state %d.\n", state
);
3051 hr
= IMFPresentationClock_Start(clock
, 0);
3052 ok(hr
== S_OK
, "Failed to stop, hr %#lx.\n", hr
);
3054 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
3055 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
3056 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
3057 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
3058 ok(rate
== 0.0f
, "Unexpected rate.\n");
3059 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
3060 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
3061 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
3062 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
3063 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.5f
);
3064 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
3065 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, -1.0f
);
3066 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
3067 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 0.0f
);
3068 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
3069 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 1.0f
);
3070 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
3072 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
3073 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
3074 ok(state
== MFCLOCK_STATE_RUNNING
, "Unexpected state %d.\n", state
);
3076 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
3077 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
3078 ok(rate
== 0.5f
, "Unexpected rate.\n");
3079 ok(!thin
, "Unexpected thinning.\n");
3081 IMFRateControl_Release(rate_control
);
3083 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
3084 ok(hr
== S_OK
, "Failed to get shutdown interface, hr %#lx.\n", hr
);
3086 /* Shutdown behavior. */
3087 hr
= IMFShutdown_GetShutdownStatus(shutdown
, NULL
);
3088 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3090 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
3091 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
3093 hr
= IMFShutdown_Shutdown(shutdown
);
3094 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3097 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
3098 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3099 ok(!!time_source
, "Unexpected instance %p.\n", time_source
);
3100 IMFPresentationTimeSource_Release(time_source
);
3102 hr
= IMFPresentationClock_GetTime(clock
, &time
);
3103 ok(hr
== S_OK
, "Failed to get time, hr %#lx.\n", hr
);
3105 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
3106 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
3107 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
3109 hr
= IMFPresentationClock_Start(clock
, 0);
3110 ok(hr
== S_OK
, "Failed to start the clock, hr %#lx.\n", hr
);
3112 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
3113 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
3114 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
3116 hr
= IMFShutdown_Shutdown(shutdown
);
3117 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3119 IMFShutdown_Release(shutdown
);
3121 IMFPresentationClock_Release(clock
);
3124 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3127 static HRESULT WINAPI
grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
, void **obj
)
3129 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
3130 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
3131 IsEqualIID(riid
, &IID_IUnknown
))
3134 IMFSampleGrabberSinkCallback_AddRef(iface
);
3139 return E_NOINTERFACE
;
3142 static ULONG WINAPI
grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
3147 static ULONG WINAPI
grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
3152 static HRESULT WINAPI
grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, LONGLONG offset
)
3157 static HRESULT WINAPI
grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
3162 static HRESULT WINAPI
grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
3167 static HRESULT WINAPI
grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
3172 static HRESULT WINAPI
grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, float rate
)
3177 static HRESULT WINAPI
grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
3178 IMFPresentationClock
*clock
)
3183 static HRESULT WINAPI
grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
3184 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
3189 static HRESULT WINAPI
grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
3194 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl
=
3196 grabber_callback_QueryInterface
,
3197 grabber_callback_AddRef
,
3198 grabber_callback_Release
,
3199 grabber_callback_OnClockStart
,
3200 grabber_callback_OnClockStop
,
3201 grabber_callback_OnClockPause
,
3202 grabber_callback_OnClockRestart
,
3203 grabber_callback_OnClockSetRate
,
3204 grabber_callback_OnSetPresentationClock
,
3205 grabber_callback_OnProcessSample
,
3206 grabber_callback_OnShutdown
,
3209 static IMFSampleGrabberSinkCallback grabber_callback
= { &grabber_callback_vtbl
};
3211 static void test_sample_grabber(void)
3213 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
3214 IMFMediaTypeHandler
*handler
, *handler2
;
3215 IMFPresentationTimeSource
*time_source
;
3216 IMFPresentationClock
*clock
, *clock2
;
3217 IMFStreamSink
*stream
, *stream2
;
3218 IMFRateSupport
*rate_support
;
3219 IMFMediaEventGenerator
*eg
;
3220 IMFMediaSink
*sink
, *sink2
;
3221 DWORD flags
, count
, id
;
3222 IMFActivate
*activate
;
3223 IMFMediaEvent
*event
;
3230 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3231 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
3233 hr
= MFCreateMediaType(&media_type
);
3234 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3236 hr
= MFCreateSampleGrabberSinkActivate(NULL
, NULL
, &activate
);
3237 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3239 hr
= MFCreateSampleGrabberSinkActivate(NULL
, &grabber_callback
, &activate
);
3240 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3242 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3243 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3244 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3245 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3247 EXPECT_REF(media_type
, 1);
3248 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3249 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3250 EXPECT_REF(media_type
, 2);
3252 hr
= IMFActivate_GetCount(activate
, &attr_count
);
3253 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
3254 ok(!attr_count
, "Unexpected count %u.\n", attr_count
);
3256 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3257 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3259 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
3260 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
3261 check_interface(sink
, &IID_IMFGetService
, TRUE
);
3262 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
3263 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
3265 if (SUCCEEDED(MFGetService((IUnknown
*)sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
)))
3267 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3268 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3269 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
3271 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3272 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3273 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
3275 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3276 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3277 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
3279 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3280 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3281 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
3283 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3284 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3285 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3287 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3288 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3289 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3291 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3292 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3293 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3295 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3296 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3297 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3299 hr
= IMFRateSupport_IsRateSupported(rate_support
, TRUE
, 1.0f
, &rate
);
3300 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3301 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
3303 IMFRateSupport_Release(rate_support
);
3306 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3307 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3308 ok(flags
& MEDIASINK_FIXED_STREAMS
, "Unexpected flags %#lx.\n", flags
);
3310 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3311 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
3312 ok(count
== 1, "Unexpected stream count %lu.\n", count
);
3314 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3315 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
3317 check_interface(stream
, &IID_IMFMediaEventGenerator
, TRUE
);
3318 check_interface(stream
, &IID_IMFMediaTypeHandler
, TRUE
);
3320 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3321 ok(hr
== S_OK
, "Failed to get stream id, hr %#lx.\n", hr
);
3322 ok(id
== 0, "Unexpected id %#lx.\n", id
);
3324 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3325 ok(hr
== S_OK
, "Failed to get media sink, hr %lx.\n", hr
);
3326 ok(sink2
== sink
, "Unexpected sink.\n");
3327 IMFMediaSink_Release(sink2
);
3329 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 1, &stream2
);
3330 ok(hr
== MF_E_INVALIDINDEX
, "Unexpected hr %#lx.\n", hr
);
3332 hr
= IMFMediaSink_GetStreamSinkById(sink
, 1, &stream2
);
3333 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3335 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3336 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3338 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
3339 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3341 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
3342 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3344 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
3346 /* Event generator. */
3347 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFMediaEventGenerator
, (void **)&eg
);
3348 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
3350 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3351 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3353 check_interface(sink
, &IID_IMFPresentationTimeSource
, FALSE
);
3355 hr
= IMFStreamSink_QueryInterface(stream
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
3356 ok(hr
== S_OK
, "Failed to get handler interface, hr %#lx.\n", hr
);
3358 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3359 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3360 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3361 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3362 ok(count
== 0, "Unexpected count %lu.\n", count
);
3363 ok(handler
== handler2
, "Unexpected handler.\n");
3365 IMFMediaTypeHandler_Release(handler
);
3366 IMFMediaTypeHandler_Release(handler2
);
3369 hr
= MFCreatePresentationClock(&clock
);
3370 ok(hr
== S_OK
, "Failed to create clock object, hr %#lx.\n", hr
);
3372 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
3373 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3375 hr
= IMFMediaSink_GetPresentationClock(sink
, &clock2
);
3376 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
3378 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
3379 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3381 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
3382 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3384 hr
= MFCreateSystemTimeSource(&time_source
);
3385 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
3387 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
3388 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
3389 IMFPresentationTimeSource_Release(time_source
);
3391 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3392 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3394 hr
= IMFActivate_ShutdownObject(activate
);
3395 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3397 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3398 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3400 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3401 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3403 /* On Win8+ this initialization happens automatically. */
3404 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3405 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3407 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
3408 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3410 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3411 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3412 ok(count
== 0, "Unexpected count %lu.\n", count
);
3414 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3415 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
3416 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid
));
3418 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
3419 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3420 ok(media_type2
== media_type
, "Unexpected media type.\n");
3421 IMFMediaType_Release(media_type2
);
3423 hr
= MFCreateMediaType(&media_type2
);
3424 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3426 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3427 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3429 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3430 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3432 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3433 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3435 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_Float
);
3436 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3438 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3439 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3441 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3442 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3444 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3445 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3447 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3448 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3449 IMFMediaType_Release(media_type
);
3451 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3452 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3454 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3455 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3456 ok(media_type2
== media_type
, "Unexpected media type.\n");
3457 IMFMediaType_Release(media_type
);
3459 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3460 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3462 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, NULL
);
3463 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3465 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3466 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3468 hr
= MFCreateMediaType(&media_type
);
3469 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3471 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3472 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3474 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
3475 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3477 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3478 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3480 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3481 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3483 media_type3
= (void *)0xdeadbeef;
3484 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3485 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3486 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3488 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_FIXED_SIZE_SAMPLES
, 1);
3489 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3491 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_SAMPLE_SIZE
, 1024);
3492 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3494 media_type3
= (void *)0xdeadbeef;
3495 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3496 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3497 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3499 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3500 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3502 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3503 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3505 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3506 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3508 EXPECT_REF(clock
, 3);
3509 hr
= IMFMediaSink_Shutdown(sink
);
3510 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3512 ref
= IMFPresentationClock_Release(clock
);
3513 ok(ref
== 0, "Release returned %ld\n", ref
);
3515 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3516 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3518 hr
= IMFMediaSink_Shutdown(sink
);
3519 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3521 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3522 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3524 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3525 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3527 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3528 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3530 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream2
);
3531 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3533 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3534 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3536 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3537 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3540 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3541 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3542 ok(id
== 1, "Unexpected id %lu.\n", id
);
3544 media_type3
= (void *)0xdeadbeef;
3545 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3546 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3547 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3549 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3550 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3552 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3553 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3555 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3556 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
3558 ref
= IMFMediaType_Release(media_type2
);
3560 ok(ref
== 0, "Release returned %ld\n", ref
);
3561 ref
= IMFMediaType_Release(media_type
);
3562 ok(ref
== 0, "Release returned %ld\n", ref
);
3564 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3565 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3567 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3568 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3570 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
3571 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3573 hr
= IMFMediaTypeHandler_GetMajorType(handler
, NULL
);
3574 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3576 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3577 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3579 IMFMediaTypeHandler_Release(handler
);
3581 handler
= (void *)0xdeadbeef;
3582 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3583 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3584 ok(handler
== (void *)0xdeadbeef, "Unexpected pointer.\n");
3586 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, NULL
);
3587 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3589 IMFMediaEventGenerator_Release(eg
);
3590 IMFStreamSink_Release(stream
);
3592 ref
= IMFActivate_Release(activate
);
3593 ok(ref
== 0, "Release returned %ld\n", ref
);
3594 ref
= IMFMediaSink_Release(sink
);
3595 ok(ref
== 0, "Release returned %ld\n", ref
);
3597 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
3598 hr
= MFCreateMediaType(&media_type
);
3599 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3601 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3602 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3603 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3604 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3606 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3607 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3609 hr
= IMFActivate_SetUINT32(activate
, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
, 1);
3610 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3612 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3613 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3615 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3616 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3617 ok(flags
& MEDIASINK_RATELESS
, "Unexpected flags %#lx.\n", flags
);
3619 hr
= IMFActivate_ShutdownObject(activate
);
3620 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3622 /* required for the sink to be fully released */
3623 hr
= IMFMediaSink_Shutdown(sink
);
3624 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3626 ref
= IMFActivate_Release(activate
);
3627 ok(ref
== 0, "Release returned %ld\n", ref
);
3628 ref
= IMFMediaSink_Release(sink
);
3629 ok(ref
== 0, "Release returned %ld\n", ref
);
3632 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3633 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3635 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3636 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3638 hr
= IMFActivate_ShutdownObject(activate
);
3639 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3641 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
3642 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3644 hr
= IMFActivate_GetCount(activate
, &attr_count
);
3645 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3647 hr
= IMFActivate_DetachObject(activate
);
3648 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3650 ref
= IMFActivate_Release(activate
);
3651 ok(ref
== 0, "Release returned %ld\n", ref
);
3653 /* required for the sink to be fully released */
3654 hr
= IMFMediaSink_Shutdown(sink
);
3655 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3657 ref
= IMFMediaSink_Release(sink
);
3658 ok(ref
== 0, "Release returned %ld\n", ref
);
3660 ref
= IMFMediaType_Release(media_type
);
3661 ok(ref
== 0, "Release returned %ld\n", ref
);
3664 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3667 static void test_sample_grabber_is_mediatype_supported(void)
3669 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
3670 IMFMediaTypeHandler
*handler
;
3671 IMFActivate
*activate
;
3672 IMFStreamSink
*stream
;
3678 /* IsMediaTypeSupported checks are done against the creation type, and check format data */
3679 hr
= MFCreateMediaType(&media_type
);
3680 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3682 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3683 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3684 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3685 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3686 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3687 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3689 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3690 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3692 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3693 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3695 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3696 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
3697 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3698 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3699 IMFStreamSink_Release(stream
);
3701 /* On Win8+ this initialization happens automatically. */
3702 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3703 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3705 hr
= MFCreateMediaType(&media_type2
);
3706 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3708 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3709 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3710 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3711 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3712 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3713 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3715 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3716 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3718 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3719 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Failed to set media type, hr %#lx.\n", hr
);
3721 /* Make it match grabber type sample rate. */
3722 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3723 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3725 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3726 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3728 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3729 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3730 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type3
);
3731 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3732 ok(media_type3
== media_type2
, "Unexpected media type instance.\n");
3733 IMFMediaType_Release(media_type3
);
3735 /* Change original type. */
3736 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3737 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3739 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3740 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3742 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3743 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3745 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3746 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3748 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3749 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3750 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3752 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3753 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3755 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3756 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3757 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3759 IMFMediaTypeHandler_Release(handler
);
3761 hr
= IMFActivate_ShutdownObject(activate
);
3762 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3764 ref
= IMFActivate_Release(activate
);
3765 ok(ref
== 0, "Release returned %ld\n", ref
);
3767 /* required for the sink to be fully released */
3768 hr
= IMFMediaSink_Shutdown(sink
);
3769 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3771 ref
= IMFMediaSink_Release(sink
);
3772 ok(ref
== 0, "Release returned %ld\n", ref
);
3774 ref
= IMFMediaType_Release(media_type2
);
3775 ok(ref
== 0, "Release returned %ld\n", ref
);
3776 ref
= IMFMediaType_Release(media_type
);
3777 ok(ref
== 0, "Release returned %ld\n", ref
);
3780 static BOOL
is_supported_video_type(const GUID
*guid
)
3782 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
3783 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
3784 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
3785 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
3786 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
3787 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
3788 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
3789 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
3790 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
3791 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
3792 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
3793 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
3794 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
3795 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
3796 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
3797 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
3798 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
3799 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
3800 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
3801 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
3802 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
3803 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
3804 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
3805 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
3806 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
3807 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
3808 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
3809 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
3810 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
3811 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
3812 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
3815 static void test_video_processor(void)
3817 const GUID transform_inputs
[22] =
3823 MFVideoFormat_ARGB32
,
3824 MFVideoFormat_RGB32
,
3829 MFVideoFormat_RGB24
,
3830 MFVideoFormat_RGB555
,
3831 MFVideoFormat_RGB565
,
3842 const GUID transform_outputs
[21] =
3848 MFVideoFormat_ARGB32
,
3849 MFVideoFormat_RGB32
,
3854 MFVideoFormat_RGB24
,
3855 MFVideoFormat_RGB555
,
3856 MFVideoFormat_RGB565
,
3866 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3867 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
3868 DWORD input_count
, output_count
, input_id
, output_id
, flags
;
3869 DWORD input_min
, input_max
, output_min
, output_max
, i
;
3870 IMFAttributes
*attributes
, *attributes2
;
3871 IMFMediaType
*media_type
, *media_type2
;
3872 MFT_OUTPUT_DATA_BUFFER output_buffer
;
3873 MFT_OUTPUT_STREAM_INFO output_info
;
3874 MFT_INPUT_STREAM_INFO input_info
;
3875 IMFSample
*sample
, *sample2
;
3876 IMFTransform
*transform
;
3877 IMFMediaBuffer
*buffer
;
3878 IMFMediaEvent
*event
;
3886 hr
= CoInitialize(NULL
);
3887 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3889 if (!create_transform(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, L
"Microsoft Video Processor MFT", &MFMediaType_Video
,
3890 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
3891 &transform
, &CLSID_VideoProcessorMFT
, &class_id
))
3893 has_video_processor
= TRUE
;
3896 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
3898 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
3899 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
3900 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
3902 /* Transform global attributes. */
3903 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3904 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3906 hr
= IMFAttributes_GetCount(attributes
, &count
);
3907 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3909 ok(!!count
, "Unexpected attribute count %u.\n", count
);
3912 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D11_AWARE
, &value
);
3914 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3915 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
3917 hr
= IMFTransform_GetAttributes(transform
, &attributes2
);
3918 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3919 ok(attributes
== attributes2
, "Unexpected instance.\n");
3920 IMFAttributes_Release(attributes
);
3921 IMFAttributes_Release(attributes2
);
3923 hr
= IMFTransform_GetStreamLimits(transform
, &input_min
, &input_max
, &output_min
, &output_max
);
3924 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
3925 ok(input_min
== input_max
&& input_min
== 1 && output_min
== output_max
&& output_min
== 1,
3926 "Unexpected stream limits.\n");
3928 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
3929 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
3930 ok(input_count
== 1 && output_count
== 1, "Unexpected stream count %lu, %lu.\n", input_count
, output_count
);
3932 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
3933 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3936 hr
= IMFTransform_AddInputStreams(transform
, 1, &input_id
);
3937 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3939 hr
= IMFTransform_DeleteInputStream(transform
, 0);
3940 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3942 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3944 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3946 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
3947 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3949 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
3951 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3953 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
3954 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3955 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes2
);
3956 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3957 ok(attributes
== attributes2
, "Unexpected instance.\n");
3958 IMFAttributes_Release(attributes
);
3959 IMFAttributes_Release(attributes2
);
3961 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3963 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3965 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
3967 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3969 hr
= IMFTransform_GetInputCurrentType(transform
, 1, &media_type
);
3971 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3973 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
3975 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3977 hr
= IMFTransform_GetOutputCurrentType(transform
, 1, &media_type
);
3979 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3981 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
3983 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3985 memset(&input_info
, 0xcc, sizeof(input_info
));
3986 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3988 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3989 ok(input_info
.dwFlags
== 0, "Unexpected flag %#lx.\n", input_info
.dwFlags
);
3990 ok(input_info
.cbSize
== 0, "Unexpected size %lu.\n", input_info
.cbSize
);
3991 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
3992 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
3994 hr
= MFCreateMediaEvent(MEUnknown
, &GUID_NULL
, S_OK
, NULL
, &event
);
3995 ok(hr
== S_OK
, "Failed to create event object, hr %#lx.\n", hr
);
3996 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
3997 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3998 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
3999 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4000 ref
= IMFMediaEvent_Release(event
);
4001 ok(ref
== 0, "Release returned %ld\n", ref
);
4003 /* Configure stream types. */
4006 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
4009 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4013 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
4014 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
4015 ok(media_type
!= media_type2
, "Unexpected instance.\n");
4016 ref
= IMFMediaType_Release(media_type2
);
4017 ok(ref
== 0, "Release returned %ld\n", ref
);
4019 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
4020 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4021 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
4023 hr
= IMFMediaType_GetCount(media_type
, &count
);
4024 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
4025 ok(count
== 2, "Unexpected count %u.\n", count
);
4027 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
4028 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
4029 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
4031 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
4032 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4034 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4035 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4037 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
4038 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4040 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
4041 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
4042 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
4043 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
4045 ref
= IMFMediaType_Release(media_type
);
4046 ok(ref
== 0, "Release returned %ld\n", ref
);
4050 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
4051 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4053 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
4054 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
4056 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4057 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
4059 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
4060 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
4061 ok(media_type
!= media_type2
, "Unexpected instance.\n");
4062 IMFMediaType_Release(media_type2
);
4064 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
4065 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
4066 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
4068 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
4069 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
4070 ok(input_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
4071 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
4072 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
4074 IMFMediaType_Release(media_type
);
4078 hr
= MFCreateMediaType(&media_type
);
4079 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4081 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4082 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4084 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
4085 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4087 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
4088 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4090 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4092 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
4094 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4095 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4097 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
4099 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
4101 memset(&output_info
, 0, sizeof(output_info
));
4102 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
4104 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
4105 ok(output_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
4107 ok(output_info
.cbSize
> 0, "Unexpected size %lu.\n", output_info
.cbSize
);
4108 ok(output_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
4110 hr
= MFCreateSample(&sample
);
4111 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
4113 hr
= MFCreateSample(&sample2
);
4114 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
4116 memset(&output_buffer
, 0, sizeof(output_buffer
));
4117 output_buffer
.pSample
= sample
;
4119 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
4121 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
4122 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
4123 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
4125 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
4127 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
4129 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
4131 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
4133 memset(&output_buffer
, 0, sizeof(output_buffer
));
4134 output_buffer
.pSample
= sample
;
4136 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
4138 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
4139 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
4140 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
4142 hr
= IMFSample_SetSampleTime(sample2
, 0);
4143 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
4144 memset(&output_buffer
, 0, sizeof(output_buffer
));
4145 output_buffer
.pSample
= sample
;
4147 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
4149 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4150 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
4151 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
4153 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
4154 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
4156 hr
= IMFSample_AddBuffer(sample2
, buffer
);
4157 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
4159 hr
= IMFSample_AddBuffer(sample
, buffer
);
4160 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
4162 memset(&output_buffer
, 0, sizeof(output_buffer
));
4163 output_buffer
.pSample
= sample
;
4165 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
4167 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
4168 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
4169 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
4173 memset(&output_buffer
, 0, sizeof(output_buffer
));
4174 output_buffer
.pSample
= sample
;
4176 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
4177 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
4178 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
4179 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
4182 ref
= IMFTransform_Release(transform
);
4183 ok(ref
== 0, "Release returned %ld\n", ref
);
4185 ref
= IMFMediaType_Release(media_type
);
4186 ok(ref
== 0, "Release returned %ld\n", ref
);
4187 ref
= IMFSample_Release(sample2
);
4188 ok(ref
== 0, "Release returned %ld\n", ref
);
4189 ref
= IMFSample_Release(sample
);
4190 ok(ref
== 0, "Release returned %ld\n", ref
);
4191 ref
= IMFMediaBuffer_Release(buffer
);
4192 ok(ref
== 0, "Release returned %ld\n", ref
);
4198 static void test_quality_manager(void)
4200 IMFPresentationClock
*clock
;
4201 IMFQualityManager
*manager
;
4202 IMFTopology
*topology
;
4206 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4207 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4209 hr
= MFCreatePresentationClock(&clock
);
4210 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
4212 hr
= MFCreateStandardQualityManager(&manager
);
4213 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4215 check_interface(manager
, &IID_IMFQualityManager
, TRUE
);
4216 check_interface(manager
, &IID_IMFClockStateSink
, TRUE
);
4218 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
4219 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4221 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
4222 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4224 /* Set clock, then shutdown. */
4225 EXPECT_REF(clock
, 1);
4226 EXPECT_REF(manager
, 1);
4227 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
4228 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4229 EXPECT_REF(clock
, 2);
4230 EXPECT_REF(manager
, 2);
4232 hr
= IMFQualityManager_Shutdown(manager
);
4233 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4234 EXPECT_REF(clock
, 1);
4236 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
4237 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4239 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
4240 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4242 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
4243 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4245 hr
= IMFQualityManager_Shutdown(manager
);
4246 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4248 ref
= IMFQualityManager_Release(manager
);
4249 ok(ref
== 0, "Release returned %ld\n", ref
);
4251 hr
= MFCreateStandardQualityManager(&manager
);
4252 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4254 EXPECT_REF(clock
, 1);
4255 EXPECT_REF(manager
, 1);
4256 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
4257 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4258 EXPECT_REF(manager
, 2);
4259 EXPECT_REF(clock
, 2);
4260 hr
= IMFQualityManager_Shutdown(manager
);
4261 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4263 ref
= IMFQualityManager_Release(manager
);
4264 ok(ref
== 0, "Release returned %ld\n", ref
);
4265 ref
= IMFPresentationClock_Release(clock
);
4266 ok(ref
== 0, "Release returned %ld\n", ref
);
4269 hr
= MFCreateStandardQualityManager(&manager
);
4270 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4272 hr
= MFCreateTopology(&topology
);
4273 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4275 EXPECT_REF(topology
, 1);
4276 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4277 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4278 EXPECT_REF(topology
, 2);
4280 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
4281 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4282 EXPECT_REF(topology
, 1);
4284 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4285 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4287 EXPECT_REF(topology
, 2);
4288 hr
= IMFQualityManager_Shutdown(manager
);
4289 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4290 EXPECT_REF(topology
, 1);
4292 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4293 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4295 ref
= IMFQualityManager_Release(manager
);
4296 ok(ref
== 0, "Release returned %ld\n", ref
);
4298 hr
= MFCreateStandardQualityManager(&manager
);
4299 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4301 EXPECT_REF(topology
, 1);
4302 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4303 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4304 EXPECT_REF(topology
, 2);
4306 ref
= IMFQualityManager_Release(manager
);
4307 ok(ref
== 0, "Release returned %ld\n", ref
);
4308 ref
= IMFTopology_Release(topology
);
4309 ok(ref
== 0, "Release returned %ld\n", ref
);
4312 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4315 static void check_sar_rate_support(IMFMediaSink
*sink
)
4317 IMFRateSupport
*rate_support
;
4318 IMFMediaTypeHandler
*handler
;
4319 IMFStreamSink
*stream_sink
;
4320 IMFMediaType
*media_type
;
4324 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rate_support
);
4326 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4327 if (FAILED(hr
)) return;
4329 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
4330 if (hr
== MF_E_SHUTDOWN
)
4332 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4333 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4335 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4336 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4338 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4339 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4341 IMFRateSupport_Release(rate_support
);
4344 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4346 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
4347 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4349 IMFStreamSink_Release(stream_sink
);
4351 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4352 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4354 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4355 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4357 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
4360 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4361 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4363 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4364 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4366 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4367 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4369 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4370 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4372 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4373 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4375 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4376 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4378 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4379 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4381 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4382 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4384 IMFMediaType_Release(media_type
);
4388 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4389 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4391 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4392 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4394 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4395 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4397 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4398 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4400 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4401 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4403 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4404 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4406 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4407 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4409 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4410 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4413 IMFMediaTypeHandler_Release(handler
);
4414 IMFRateSupport_Release(rate_support
);
4417 static void test_sar(void)
4419 IMFPresentationClock
*present_clock
, *present_clock2
;
4420 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
4421 IMFClockStateSink
*state_sink
, *state_sink2
;
4422 IMFMediaTypeHandler
*handler
, *handler2
;
4423 IMFPresentationTimeSource
*time_source
;
4424 IMFSimpleAudioVolume
*simple_volume
;
4425 IMFAudioStreamVolume
*stream_volume
;
4426 IMFMediaSink
*sink
, *sink2
;
4427 IMFStreamSink
*stream_sink
;
4428 IMFAttributes
*attributes
;
4429 DWORD i
, id
, flags
, count
;
4430 IMFActivate
*activate
;
4431 UINT32 channel_count
;
4432 MFCLOCK_STATE state
;
4441 hr
= CoInitialize(NULL
);
4442 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4444 hr
= MFCreateAudioRenderer(NULL
, &sink
);
4445 if (hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
)
4447 skip("No audio playback device available.\n");
4451 ok(hr
== S_OK
, "Failed to create renderer, hr %#lx.\n", hr
);
4453 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4454 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4456 hr
= MFCreatePresentationClock(&present_clock
);
4457 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
4459 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&time_source
);
4461 ok(hr
== S_OK
, "Failed to get time source interface, hr %#lx.\n", hr
);
4465 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink2
);
4466 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4467 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4468 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4469 ok(state_sink
== state_sink2
, "Unexpected clock sink.\n");
4470 IMFClockStateSink_Release(state_sink2
);
4471 IMFClockStateSink_Release(state_sink
);
4473 hr
= IMFPresentationTimeSource_GetUnderlyingClock(time_source
, &clock
);
4474 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
4476 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &flags
);
4477 ok(hr
== S_OK
, "Failed to get flags, hr %#lx.\n", hr
);
4478 ok(flags
== MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
, "Unexpected flags %#lx.\n", flags
);
4480 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
4481 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
4482 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
4484 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4485 ok(hr
== S_OK
, "Failed to get state sink, hr %#lx.\n", hr
);
4487 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4488 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4490 IMFClockStateSink_Release(state_sink
);
4492 IMFPresentationTimeSource_Release(time_source
);
4494 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4495 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4497 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4498 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4500 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4501 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4503 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4504 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4505 ok(count
== 1, "Unexpected count %lu.\n", count
);
4507 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4508 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4509 ok(flags
== (MEDIASINK_FIXED_STREAMS
| MEDIASINK_CAN_PREROLL
), "Unexpected flags %#lx.\n", flags
);
4511 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4512 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4513 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4514 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4515 todo_wine
check_interface(sink
, &IID_IMFPresentationTimeSource
, TRUE
);
4516 todo_wine
check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4517 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, FALSE
);
4518 check_service_interface(sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, TRUE
);
4519 check_service_interface(sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, TRUE
);
4522 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4523 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4525 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4526 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4528 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4529 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4531 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4532 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4534 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4535 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4537 IMFClockStateSink_Release(state_sink
);
4539 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4540 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4542 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4544 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
4546 hr
= MFCreateSystemTimeSource(&time_source
);
4547 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
4549 hr
= IMFPresentationClock_SetTimeSource(present_clock
, time_source
);
4550 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
4551 IMFPresentationTimeSource_Release(time_source
);
4553 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4554 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4556 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4557 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4559 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4560 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4561 ok(present_clock
== present_clock2
, "Unexpected instance.\n");
4562 IMFPresentationClock_Release(present_clock2
);
4565 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
4566 ok(hr
== S_OK
, "Failed to get a stream, hr %#lx.\n", hr
);
4568 check_interface(stream_sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4569 check_interface(stream_sink
, &IID_IMFMediaTypeHandler
, TRUE
);
4570 todo_wine
check_interface(stream_sink
, &IID_IMFGetService
, TRUE
);
4572 hr
= IMFStreamSink_GetIdentifier(stream_sink
, &id
);
4573 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4574 ok(!id
, "Unexpected id.\n");
4576 hr
= IMFStreamSink_GetMediaSink(stream_sink
, &sink2
);
4577 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4578 ok(sink
== sink2
, "Unexpected object.\n");
4579 IMFMediaSink_Release(sink2
);
4581 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
4582 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4584 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
4585 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4586 ok(handler2
== handler
, "Unexpected instance.\n");
4587 IMFMediaTypeHandler_Release(handler2
);
4589 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4590 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4591 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4594 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
4595 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
4596 ok(!!count
, "Unexpected type count %lu.\n", count
);
4598 /* A number of same major/subtype entries are returned, with different degrees of finer format
4599 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
4601 for (i
= 0, found
= -1; i
< count
; ++i
)
4603 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, i
, &mediatype
);
4604 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4606 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
)))
4608 IMFMediaType_Release(mediatype
);
4610 if (found
!= -1) break;
4612 ok(found
!= -1, "Haven't found a supported type.\n");
4614 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4615 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4617 hr
= MFCreateMediaType(&mediatype
);
4618 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4620 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
4621 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4622 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4624 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4625 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4626 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4627 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4629 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
4630 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4631 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4632 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4634 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
4635 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4637 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype2
);
4638 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4640 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype3
);
4641 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4642 ok(mediatype2
== mediatype3
, "Unexpected instance.\n");
4643 IMFMediaType_Release(mediatype3
);
4645 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype2
, NULL
);
4646 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4648 IMFMediaType_Release(mediatype
);
4650 check_sar_rate_support(sink
);
4652 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype2
);
4653 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4655 check_sar_rate_support(sink
);
4657 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4658 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4659 ok(mediatype
== mediatype2
, "Unexpected instance.\n");
4660 IMFMediaType_Release(mediatype
);
4662 IMFMediaType_Release(mediatype2
);
4664 /* Reset back to uninitialized state. */
4665 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
4666 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4668 IMFMediaTypeHandler_Release(handler
);
4670 /* State change with initialized stream. */
4671 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4672 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4674 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4675 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4677 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4678 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4680 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4681 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4683 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4684 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4686 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4687 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4689 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4690 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4692 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4693 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4695 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4696 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4698 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4699 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4701 IMFClockStateSink_Release(state_sink
);
4703 IMFStreamSink_Release(stream_sink
);
4705 /* Volume control */
4706 hr
= MFGetService((IUnknown
*)sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, (void **)&simple_volume
);
4707 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4709 hr
= IMFSimpleAudioVolume_GetMute(simple_volume
, &mute
);
4710 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4712 IMFSimpleAudioVolume_Release(simple_volume
);
4714 hr
= MFGetService((IUnknown
*)sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, (void **)&stream_volume
);
4715 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4717 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, &channel_count
);
4718 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4720 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, NULL
);
4721 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4723 IMFAudioStreamVolume_Release(stream_volume
);
4725 hr
= MFGetService((IUnknown
*)sink
, &MR_AUDIO_POLICY_SERVICE
, &IID_IMFAudioPolicy
, (void **)&unk
);
4726 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4727 IUnknown_Release(unk
);
4730 EXPECT_REF(present_clock
, 2);
4731 hr
= IMFMediaSink_Shutdown(sink
);
4732 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4733 EXPECT_REF(present_clock
, 1);
4735 hr
= IMFMediaSink_Shutdown(sink
);
4736 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4738 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4739 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4741 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4742 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4744 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4745 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4747 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4748 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4750 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4751 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4753 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4754 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4756 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4757 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4759 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4760 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4762 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4763 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4765 check_sar_rate_support(sink
);
4767 ref
= IMFMediaSink_Release(sink
);
4769 ok(ref
== 0, "Release returned %ld\n", ref
);
4772 hr
= MFCreateAudioRendererActivate(&activate
);
4773 ok(hr
== S_OK
, "Failed to create activation object, hr %#lx.\n", hr
);
4775 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4776 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4778 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4779 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4780 ok(sink
== sink2
, "Unexpected instance.\n");
4781 IMFMediaSink_Release(sink2
);
4783 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4784 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
4786 hr
= IMFActivate_ShutdownObject(activate
);
4787 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4789 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4790 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4792 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4793 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4795 ok(sink
== sink2
, "Unexpected instance.\n");
4797 hr
= IMFMediaSink_GetCharacteristics(sink2
, &flags
);
4799 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4801 IMFMediaSink_Release(sink2
);
4803 hr
= IMFActivate_DetachObject(activate
);
4804 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4806 hr
= IMFActivate_ShutdownObject(activate
);
4807 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4809 ref
= IMFActivate_Release(activate
);
4810 ok(ref
== 0, "Release returned %ld\n", ref
);
4811 ref
= IMFMediaSink_Release(sink
);
4812 ok(ref
== 0, "Release returned %ld\n", ref
);
4814 ref
= IMFPresentationClock_Release(present_clock
);
4815 ok(ref
== 0, "Release returned %ld\n", ref
);
4818 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4820 /* SAR attributes */
4821 hr
= MFCreateAttributes(&attributes
, 0);
4822 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
4825 hr
= IMFAttributes_SetUINT32(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
, eMultimedia
);
4826 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4828 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4829 ok(hr
== S_OK
, "Failed to create a sink, hr %#lx.\n", hr
);
4831 /* required for the sink to be fully released */
4832 hr
= IMFMediaSink_Shutdown(sink
);
4833 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4835 ref
= IMFMediaSink_Release(sink
);
4836 ok(ref
== 0, "Release returned %ld\n", ref
);
4838 /* Invalid endpoint. */
4839 hr
= IMFAttributes_SetString(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
, L
"endpoint");
4840 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4842 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4843 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4845 hr
= IMFAttributes_DeleteItem(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
);
4846 ok(hr
== S_OK
, "Failed to remove attribute, hr %#lx.\n", hr
);
4848 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4849 ok(hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
, "Failed to create a sink, hr %#lx.\n", hr
);
4851 ref
= IMFAttributes_Release(attributes
);
4852 ok(ref
== 0, "Release returned %ld\n", ref
);
4857 static void test_evr(void)
4859 static const float supported_rates
[] =
4861 0.0f
, 1.0f
, -20.0f
, 20.0f
, 1000.0f
, -1000.0f
,
4863 IMFVideoSampleAllocatorCallback
*allocator_callback
;
4864 IMFStreamSink
*stream_sink
, *stream_sink2
;
4865 IMFVideoDisplayControl
*display_control
;
4866 IMFMediaType
*media_type
, *media_type2
;
4867 IMFPresentationTimeSource
*time_source
;
4868 IMFVideoSampleAllocator
*allocator
;
4869 IMFMediaTypeHandler
*type_handler
;
4870 IMFVideoRenderer
*video_renderer
;
4871 IMFPresentationClock
*clock
;
4872 IMFMediaSink
*sink
, *sink2
;
4873 IMFAttributes
*attributes
;
4874 UINT32 attr_count
, value
;
4875 IMFActivate
*activate
;
4876 HWND window
, window2
;
4888 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4889 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4891 hr
= MFCreateVideoRenderer(&IID_IMFVideoRenderer
, (void **)&video_renderer
);
4892 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4894 hr
= IMFVideoRenderer_InitializeRenderer(video_renderer
, NULL
, NULL
);
4895 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4897 /* required for the video renderer to be fully released */
4898 hr
= IMFVideoRenderer_QueryInterface(video_renderer
, &IID_IMFMediaSink
, (void **)&sink
);
4899 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4900 hr
= IMFMediaSink_Shutdown(sink
);
4901 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4902 IMFMediaSink_Release(sink
);
4904 ref
= IMFVideoRenderer_Release(video_renderer
);
4905 ok(ref
== 0, "Release returned %ld\n", ref
);
4907 hr
= MFCreateVideoRendererActivate(NULL
, NULL
);
4908 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4911 window
= create_window();
4912 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4913 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4915 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4916 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4917 ok(UlongToHandle(window3
) == window
, "Unexpected value.\n");
4919 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4920 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4922 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4923 check_interface(sink
, &IID_IMFVideoRenderer
, TRUE
);
4924 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4925 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4926 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4927 check_interface(sink
, &IID_IMFQualityAdvise
, TRUE
);
4928 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
4929 check_interface(sink
, &IID_IMFRateControl
, FALSE
);
4930 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
4931 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
4932 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
4933 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
4934 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
4935 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
4936 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, FALSE
);
4937 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
4938 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4940 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
,
4941 (void **)&display_control
);
4942 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4945 hr
= IMFVideoDisplayControl_GetVideoWindow(display_control
, &window2
);
4946 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4947 ok(window2
== window
, "Unexpected window %p.\n", window2
);
4949 IMFVideoDisplayControl_Release(display_control
);
4951 hr
= IMFActivate_ShutdownObject(activate
);
4952 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4954 ref
= IMFActivate_Release(activate
);
4955 ok(ref
== 0, "Release returned %ld\n", ref
);
4956 ref
= IMFMediaSink_Release(sink
);
4957 ok(ref
== 0, "Release returned %ld\n", ref
);
4958 DestroyWindow(window
);
4960 hr
= MFCreateVideoRendererActivate(NULL
, &activate
);
4961 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4963 hr
= IMFActivate_GetCount(activate
, &attr_count
);
4964 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
4965 ok(attr_count
== 1, "Unexpected count %u.\n", attr_count
);
4967 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4968 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4969 ok(!window3
, "Unexpected value.\n");
4971 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4972 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4974 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFAttributes
, (void **)&attributes
);
4975 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4976 check_interface(attributes
, &IID_IMFMediaSink
, TRUE
);
4978 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4979 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4980 ok(!!attr_count
, "Unexpected count %u.\n", attr_count
);
4981 /* Rendering preferences are not immediately propagated to the presenter. */
4982 hr
= IMFAttributes_SetUINT32(attributes
, &EVRConfig_ForceBob
, 1);
4983 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4984 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, (void **)&display_control
);
4985 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4986 hr
= IMFVideoDisplayControl_GetRenderingPrefs(display_control
, &flags
);
4987 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4988 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
4989 IMFVideoDisplayControl_Release(display_control
);
4990 IMFAttributes_Release(attributes
);
4992 /* Primary stream type handler. */
4993 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4994 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4996 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFAttributes
, (void **)&attributes
);
4997 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4998 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4999 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5000 ok(attr_count
== 2, "Unexpected count %u.\n", attr_count
);
5002 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, &value
);
5003 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5004 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
5006 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D_AWARE
, &value
);
5007 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5008 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
5010 check_interface(attributes
, &IID_IMFStreamSink
, TRUE
);
5011 IMFAttributes_Release(attributes
);
5013 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
5014 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5016 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, NULL
);
5017 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5019 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, &guid
);
5020 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5021 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
5023 /* Supported types are not advertised. */
5024 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, NULL
);
5025 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5028 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, &count
);
5029 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5030 ok(!count
, "Unexpected count %lu.\n", count
);
5032 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, NULL
);
5033 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5035 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, &media_type
);
5036 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5038 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, NULL
);
5039 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5041 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type
);
5042 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5044 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, NULL
);
5045 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5047 hr
= MFCreateMediaType(&media_type
);
5048 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5050 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5051 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5053 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5054 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5056 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
5057 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5059 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, NULL
, NULL
);
5060 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5062 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
5063 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
5065 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
5066 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5068 media_type2
= (void *)0x1;
5069 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
5070 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5071 ok(!media_type2
, "Unexpected media type %p.\n", media_type2
);
5073 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
5074 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5076 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type2
);
5077 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5078 check_interface(media_type2
, &IID_IMFVideoMediaType
, TRUE
);
5079 IMFMediaType_Release(media_type2
);
5081 IMFMediaType_Release(media_type
);
5083 IMFMediaTypeHandler_Release(type_handler
);
5085 /* Stream uses an allocator. */
5086 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, TRUE
);
5087 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
5089 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
5090 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
5091 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
5092 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
5093 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
5094 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
5095 check_service_interface(stream_sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
5097 hr
= MFGetService((IUnknown
*)stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
5098 (void **)&allocator
);
5099 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5101 hr
= IMFVideoSampleAllocator_QueryInterface(allocator
, &IID_IMFVideoSampleAllocatorCallback
, (void **)&allocator_callback
);
5102 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5105 hr
= IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback
, &sample_count
);
5106 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5107 ok(!sample_count
, "Unexpected sample count %ld.\n", sample_count
);
5109 hr
= IMFVideoSampleAllocator_AllocateSample(allocator
, &sample
);
5110 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
5112 IMFVideoSampleAllocatorCallback_Release(allocator_callback
);
5113 IMFVideoSampleAllocator_Release(allocator
);
5114 IMFStreamSink_Release(stream_sink
);
5116 /* Same test for a substream. */
5117 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream_sink2
);
5118 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "Unexpected hr %#lx.\n", hr
);
5122 hr
= MFGetService((IUnknown
*)stream_sink2
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
5123 (void **)&allocator
);
5124 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5125 IMFVideoSampleAllocator_Release(allocator
);
5127 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
5128 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5130 ref
= IMFStreamSink_Release(stream_sink2
);
5131 ok(ref
== 0, "Release returned %ld\n", ref
);
5134 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
5135 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5136 ok(flags
== (MEDIASINK_CAN_PREROLL
| MEDIASINK_CLOCK_REQUIRED
), "Unexpected flags %#lx.\n", flags
);
5138 hr
= IMFActivate_ShutdownObject(activate
);
5139 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
5141 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
5142 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5144 /* Activate again. */
5145 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
5146 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
5148 ok(sink
== sink2
, "Unexpected instance.\n");
5149 IMFMediaSink_Release(sink2
);
5151 hr
= IMFActivate_DetachObject(activate
);
5152 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5154 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
5155 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5157 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
5158 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
5160 ok(sink
== sink2
, "Unexpected instance.\n");
5161 IMFMediaSink_Release(sink2
);
5163 hr
= IMFActivate_ShutdownObject(activate
);
5164 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
5166 ref
= IMFActivate_Release(activate
);
5167 ok(ref
== 0, "Release returned %ld\n", ref
);
5168 ref
= IMFMediaSink_Release(sink
);
5170 ok(ref
== 0, "Release returned %ld\n", ref
);
5173 window
= create_window();
5175 hr
= MFCreateVideoRendererActivate(window
, &activate
);
5176 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
5178 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
5179 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5180 ref
= IMFActivate_Release(activate
);
5181 ok(ref
== 0, "Release returned %ld\n", ref
);
5183 hr
= MFCreateSystemTimeSource(&time_source
);
5184 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5186 hr
= MFCreatePresentationClock(&clock
);
5187 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5189 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
5190 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5191 IMFPresentationTimeSource_Release(time_source
);
5193 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
5194 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5196 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rs
);
5197 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5200 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5201 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5202 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5205 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
5206 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5207 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5210 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
5211 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5212 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5215 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
5216 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5217 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5219 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5220 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5222 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
5223 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5225 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
5226 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5228 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
5229 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5231 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
5232 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5234 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
5236 rate
= supported_rates
[i
] + 1.0f
;
5237 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
5238 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5239 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5241 rate
= supported_rates
[i
] + 1.0f
;
5242 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
5243 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5244 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5246 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
5247 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5249 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
5250 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
5253 /* Configuring stream type make rate support work. */
5254 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
5255 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5256 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
5257 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5258 hr
= MFCreateMediaType(&media_type
);
5259 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5260 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5261 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5262 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5263 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5264 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)64 << 32 | 64);
5265 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5266 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
5267 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5268 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
5269 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5270 IMFMediaType_Release(media_type
);
5271 IMFMediaTypeHandler_Release(type_handler
);
5272 IMFStreamSink_Release(stream_sink
);
5275 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
5276 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5277 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5280 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
5281 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5282 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
5285 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
5286 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5287 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
5290 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
5291 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5292 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
5294 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
5295 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5297 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
5298 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5300 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
5302 rate
= supported_rates
[i
] + 1.0f
;
5303 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
5304 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5305 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5307 rate
= supported_rates
[i
] + 1.0f
;
5308 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
5309 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5310 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5312 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
5313 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5315 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
5316 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5319 hr
= IMFMediaSink_Shutdown(sink
);
5320 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5322 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
5323 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5325 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
5326 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5328 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5329 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5331 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5332 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5334 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
5335 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5337 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
5338 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5340 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, 1.0f
, &rate
);
5341 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5343 ref
= IMFRateSupport_Release(rs
);
5344 ok(ref
== 1, "Release returned %ld\n", ref
);
5345 ref
= IMFMediaSink_Release(sink
);
5346 ok(ref
== 0, "Release returned %ld\n", ref
);
5347 ref
= IMFPresentationClock_Release(clock
);
5348 ok(ref
== 0, "Release returned %ld\n", ref
);
5350 DestroyWindow(window
);
5353 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
5356 static void test_MFCreateSimpleTypeHandler(void)
5358 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
5359 IMFMediaTypeHandler
*handler
;
5365 hr
= MFCreateSimpleTypeHandler(&handler
);
5366 ok(hr
== S_OK
, "Failed to create object, hr %#lx.\n", hr
);
5368 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
5369 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5371 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
5372 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
5375 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
5376 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
5377 ok(count
== 1, "Unexpected count %lu.\n", count
);
5379 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
5380 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5382 media_type
= (void *)0xdeadbeef;
5383 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
5384 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5385 ok(!media_type
, "Unexpected pointer.\n");
5387 hr
= MFCreateMediaType(&media_type
);
5388 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5390 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
5391 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
5393 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
5394 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5396 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type2
);
5397 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5398 ok(media_type2
== media_type
, "Unexpected type.\n");
5399 IMFMediaType_Release(media_type2
);
5401 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
5402 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5404 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
5405 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5407 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type2
);
5408 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5410 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 1, &media_type2
);
5411 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5413 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
5414 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5415 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5416 IMFMediaType_Release(media_type2
);
5418 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5419 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
5421 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5422 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5424 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5425 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5426 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
5428 hr
= MFCreateMediaType(&media_type3
);
5429 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5431 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, NULL
);
5432 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5434 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
5435 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5437 /* Different major types. */
5438 media_type2
= (void *)0xdeadbeef;
5439 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5440 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5441 ok(!media_type2
, "Unexpected pointer.\n");
5443 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5444 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5446 media_type2
= (void *)0xdeadbeef;
5447 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5448 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5449 ok(!media_type2
, "Unexpected pointer.\n");
5451 /* Handler missing subtype. */
5452 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
5453 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5455 media_type2
= (void *)0xdeadbeef;
5456 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5457 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5458 ok(!media_type2
, "Unexpected pointer.\n");
5460 /* Different subtypes. */
5461 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
5462 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5464 media_type2
= (void *)0xdeadbeef;
5465 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5466 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5467 ok(!media_type2
, "Unexpected pointer.\n");
5469 /* Same major/subtype. */
5470 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
5471 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5473 media_type2
= (void *)0xdeadbeef;
5474 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5475 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5476 ok(!media_type2
, "Unexpected pointer.\n");
5478 /* Set one more attribute. */
5479 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)4 << 32 | 4);
5480 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5482 media_type2
= (void *)0xdeadbeef;
5483 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5484 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5485 ok(!media_type2
, "Unexpected pointer.\n");
5487 ref
= IMFMediaType_Release(media_type3
);
5488 ok(ref
== 0, "Release returned %ld\n", ref
);
5490 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
5491 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5493 media_type2
= (void *)0xdeadbeef;
5494 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
5495 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5496 ok(!media_type2
, "Unexpected pointer.\n");
5498 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5499 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
5501 ref
= IMFMediaTypeHandler_Release(handler
);
5502 ok(ref
== 0, "Release returned %ld\n", ref
);
5503 ref
= IMFMediaType_Release(media_type
);
5504 ok(ref
== 0, "Release returned %ld\n", ref
);
5507 static void test_MFGetSupportedMimeTypes(void)
5512 hr
= MFGetSupportedMimeTypes(NULL
);
5513 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5515 value
.vt
= VT_EMPTY
;
5516 hr
= MFGetSupportedMimeTypes(&value
);
5517 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5518 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5520 PropVariantClear(&value
);
5523 static void test_MFGetSupportedSchemes(void)
5528 hr
= MFGetSupportedSchemes(NULL
);
5529 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5531 value
.vt
= VT_EMPTY
;
5532 hr
= MFGetSupportedSchemes(&value
);
5533 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5534 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5536 PropVariantClear(&value
);
5539 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
5545 hr
= IMFMediaType_GetMajorType(type
, &major
);
5546 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5548 hr
= IMFMediaType_GetCount(type
, &count
);
5549 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
5550 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5552 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
5555 static void test_sample_copier(void)
5557 IMFAttributes
*attributes
, *attributes2
;
5558 DWORD in_min
, in_max
, out_min
, out_max
;
5559 IMFMediaType
*mediatype
, *mediatype2
;
5560 MFT_OUTPUT_STREAM_INFO output_info
;
5561 IMFSample
*sample
, *client_sample
;
5562 MFT_INPUT_STREAM_INFO input_info
;
5563 DWORD input_count
, output_count
;
5564 MFT_OUTPUT_DATA_BUFFER buffer
;
5565 IMFMediaBuffer
*media_buffer
;
5566 IMFTransform
*copier
;
5567 DWORD flags
, status
;
5568 UINT32 value
, count
;
5572 if (!pMFCreateSampleCopierMFT
)
5574 win_skip("MFCreateSampleCopierMFT() is not available.\n");
5578 hr
= pMFCreateSampleCopierMFT(&copier
);
5579 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5581 hr
= IMFTransform_GetAttributes(copier
, &attributes
);
5582 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5583 hr
= IMFTransform_GetAttributes(copier
, &attributes2
);
5584 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5585 ok(attributes
== attributes2
, "Unexpected instance.\n");
5586 IMFAttributes_Release(attributes2
);
5587 hr
= IMFAttributes_GetCount(attributes
, &count
);
5588 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5589 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5590 hr
= IMFAttributes_GetUINT32(attributes
, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, &value
);
5591 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5592 ok(!!value
, "Unexpected value %u.\n", value
);
5593 ref
= IMFAttributes_Release(attributes
);
5594 ok(ref
== 1, "Release returned %ld\n", ref
);
5596 hr
= IMFTransform_GetInputStreamAttributes(copier
, 0, &attributes
);
5597 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5599 hr
= IMFTransform_GetInputStreamAttributes(copier
, 1, &attributes
);
5600 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5602 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 0, &attributes
);
5603 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5605 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 1, &attributes
);
5606 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5608 hr
= IMFTransform_SetOutputBounds(copier
, 0, 0);
5609 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5611 /* No dynamic streams. */
5612 input_count
= output_count
= 0;
5613 hr
= IMFTransform_GetStreamCount(copier
, &input_count
, &output_count
);
5614 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
5615 ok(input_count
== 1 && output_count
== 1, "Unexpected streams count.\n");
5617 hr
= IMFTransform_GetStreamLimits(copier
, &in_min
, &in_max
, &out_min
, &out_max
);
5618 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
5619 ok(in_min
== in_max
&& in_min
== 1 && out_min
== out_max
&& out_min
== 1, "Unexpected stream limits.\n");
5621 hr
= IMFTransform_GetStreamIDs(copier
, 1, &input_count
, 1, &output_count
);
5622 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5624 hr
= IMFTransform_DeleteInputStream(copier
, 0);
5625 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5627 /* Available types. */
5628 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
5629 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5630 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5631 IMFMediaType_Release(mediatype
);
5633 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
5634 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5635 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5636 IMFMediaType_Release(mediatype
);
5638 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
5639 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5641 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
5642 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5644 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
5645 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5647 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
5648 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5650 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype
);
5651 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5653 hr
= IMFTransform_GetInputCurrentType(copier
, 1, &mediatype
);
5654 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5656 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype
);
5657 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5659 hr
= IMFTransform_GetOutputCurrentType(copier
, 1, &mediatype
);
5660 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5662 hr
= MFCreateSample(&sample
);
5663 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5665 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5666 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5668 hr
= MFCreateMediaType(&mediatype
);
5669 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5671 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5672 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
5674 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5675 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5677 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
5678 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5680 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5681 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5683 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5684 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5685 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5686 ok(!output_info
.cbSize
, "Unexpected size %lu.\n", output_info
.cbSize
);
5687 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5689 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5690 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5692 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5693 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5694 ok(!input_info
.cbSize
, "Unexpected size %lu.\n", input_info
.cbSize
);
5695 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5696 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5698 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5699 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5701 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5702 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5703 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5704 ok(output_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", output_info
.cbSize
);
5705 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5707 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5708 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5709 IMFMediaType_Release(mediatype2
);
5711 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5712 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5714 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5715 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5717 /* Setting input type resets output type. */
5718 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5719 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5720 IMFMediaType_Release(mediatype2
);
5722 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5723 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5725 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5726 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5728 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
5729 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5730 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
5731 IMFMediaType_Release(mediatype2
);
5733 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5734 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5735 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5736 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5737 ok(input_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", input_info
.cbSize
);
5738 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5739 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5741 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
5742 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5743 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
5744 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5745 IMFMediaType_Release(mediatype2
);
5747 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5748 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5749 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
5751 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5752 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5753 IMFMediaType_Release(mediatype2
);
5755 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5756 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5758 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5759 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
5761 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5762 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5763 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5765 /* Pushing samples. */
5766 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5767 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5769 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
5770 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5771 IMFMediaBuffer_Release(media_buffer
);
5773 EXPECT_REF(sample
, 1);
5774 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5775 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5776 EXPECT_REF(sample
, 2);
5778 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5779 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5780 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5782 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5783 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5784 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
5786 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5787 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
5789 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5790 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5792 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5793 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5795 hr
= MFCreateSample(&client_sample
);
5796 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5798 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
5799 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5800 IMFMediaBuffer_Release(media_buffer
);
5803 memset(&buffer
, 0, sizeof(buffer
));
5804 buffer
.pSample
= client_sample
;
5805 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5806 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5807 EXPECT_REF(sample
, 1);
5809 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5810 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
5813 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5814 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5815 EXPECT_REF(sample
, 2);
5817 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
5818 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
5820 ref
= IMFSample_Release(sample
);
5821 ok(ref
== 0, "Release returned %ld\n", ref
);
5822 ref
= IMFSample_Release(client_sample
);
5823 ok(ref
== 0, "Release returned %ld\n", ref
);
5825 ref
= IMFTransform_Release(copier
);
5826 ok(ref
== 0, "Release returned %ld\n", ref
);
5827 ref
= IMFMediaType_Release(mediatype
);
5828 ok(ref
== 0, "Release returned %ld\n", ref
);
5831 struct sample_metadata
5838 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
5839 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
5841 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
5842 IMFSample
*input_sample
, *output_sample
;
5843 MFT_OUTPUT_DATA_BUFFER buffer
;
5844 DWORD flags
, status
;
5849 hr
= MFCreateSample(&input_sample
);
5850 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5854 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
5855 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5857 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
5858 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5860 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
5861 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5864 hr
= MFCreateSample(&output_sample
);
5865 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5867 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
5868 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5870 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
5871 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5873 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
5874 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5876 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
5877 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5879 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
5880 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5882 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
5883 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5886 memset(&buffer
, 0, sizeof(buffer
));
5887 buffer
.pSample
= output_sample
;
5888 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5889 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5891 if (!md
) md
= &zero_md
;
5893 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
5894 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5895 ok(md
->flags
== flags
, "Unexpected flags.\n");
5896 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
5897 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5898 ok(md
->time
== time
, "Unexpected time.\n");
5899 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
5900 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5901 ok(md
->duration
== time
, "Unexpected duration.\n");
5903 ref
= IMFSample_Release(input_sample
);
5904 ok(ref
== 0, "Release returned %ld\n", ref
);
5905 ref
= IMFSample_Release(output_sample
);
5906 ok(ref
== 0, "Release returned %ld\n", ref
);
5909 static void test_sample_copier_output_processing(void)
5911 IMFMediaBuffer
*input_buffer
, *output_buffer
;
5912 MFT_OUTPUT_STREAM_INFO output_info
;
5913 struct sample_metadata md
;
5914 IMFMediaType
*mediatype
;
5915 IMFTransform
*copier
;
5921 if (!pMFCreateSampleCopierMFT
)
5924 hr
= pMFCreateSampleCopierMFT(&copier
);
5925 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5927 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
5928 hr
= MFCreateMediaType(&mediatype
);
5929 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5931 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5932 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5934 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5935 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5937 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5938 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5940 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5941 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5943 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5944 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5946 /* Source and destination are linear buffers, destination is twice as large. */
5947 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5948 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5950 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
5951 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5953 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5954 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5955 memset(ptr
, 0xcc, max_length
);
5956 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5957 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5959 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
5960 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5962 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
5963 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5964 memset(ptr
, 0xaa, max_length
);
5965 hr
= IMFMediaBuffer_Unlock(input_buffer
);
5966 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5967 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
5968 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5970 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
5972 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5973 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5974 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
5976 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5977 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5982 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
5984 ref
= IMFMediaBuffer_Release(input_buffer
);
5985 ok(ref
== 0, "Release returned %ld\n", ref
);
5986 ref
= IMFMediaBuffer_Release(output_buffer
);
5987 ok(ref
== 0, "Release returned %ld\n", ref
);
5989 ref
= IMFTransform_Release(copier
);
5990 ok(ref
== 0, "Release returned %ld\n", ref
);
5991 ref
= IMFMediaType_Release(mediatype
);
5992 ok(ref
== 0, "Release returned %ld\n", ref
);
5995 static void test_MFGetTopoNodeCurrentType(void)
5997 static const struct attribute_desc media_type_desc
[] =
5999 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6000 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6001 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6004 IMFMediaType
*media_type
, *input_types
[2], *output_types
[2];
6005 IMFStreamDescriptor
*input_descriptor
, *output_descriptor
;
6006 struct test_stream_sink stream_sink
= test_stream_sink
;
6007 IMFMediaTypeHandler
*input_handler
, *output_handler
;
6008 IMFTransform
*transform
;
6009 IMFTopologyNode
*node
;
6014 if (!pMFGetTopoNodeCurrentType
)
6016 win_skip("MFGetTopoNodeCurrentType() is unsupported.\n");
6020 hr
= CoInitialize(NULL
);
6021 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6023 hr
= MFCreateMediaType(&input_types
[0]);
6024 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
6025 init_media_type(input_types
[0], media_type_desc
, -1);
6026 hr
= MFCreateMediaType(&input_types
[1]);
6027 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
6028 init_media_type(input_types
[1], media_type_desc
, -1);
6029 hr
= MFCreateMediaType(&output_types
[0]);
6030 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
6031 init_media_type(output_types
[0], media_type_desc
, -1);
6032 hr
= MFCreateMediaType(&output_types
[1]);
6033 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
6034 init_media_type(output_types
[1], media_type_desc
, -1);
6036 hr
= MFCreateStreamDescriptor(0, 2, input_types
, &input_descriptor
);
6037 ok(hr
== S_OK
, "Failed to create IMFStreamDescriptor hr %#lx.\n", hr
);
6038 hr
= IMFStreamDescriptor_GetMediaTypeHandler(input_descriptor
, &input_handler
);
6039 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6040 hr
= MFCreateStreamDescriptor(0, 2, output_types
, &output_descriptor
);
6041 ok(hr
== S_OK
, "Failed to create IMFStreamDescriptor hr %#lx.\n", hr
);
6042 hr
= IMFStreamDescriptor_GetMediaTypeHandler(output_descriptor
, &output_handler
);
6043 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6045 hr
= CoCreateInstance(&CLSID_CColorConvertDMO
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
6046 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6050 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
6051 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
6052 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6053 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
6054 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6055 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
6057 /* Set second output. */
6058 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, output_types
[1]);
6059 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6060 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6061 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6062 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6063 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6064 hr
= pMFGetTopoNodeCurrentType(node
, 1, TRUE
, &media_type
);
6065 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6066 hr
= pMFGetTopoNodeCurrentType(node
, 1, FALSE
, &media_type
);
6067 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6069 /* Set first output. */
6070 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, output_types
[0]);
6071 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6072 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6073 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6074 ok(media_type
== output_types
[0], "Unexpected pointer.\n");
6075 IMFMediaType_Release(media_type
);
6076 hr
= pMFGetTopoNodeCurrentType(node
, 1, TRUE
, &media_type
);
6077 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6078 ok(media_type
== output_types
[0], "Unexpected pointer.\n");
6079 IMFMediaType_Release(media_type
);
6080 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6081 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6082 ok(media_type
== output_types
[0], "Unexpected pointer.\n");
6083 IMFMediaType_Release(media_type
);
6085 /* Set primary output. */
6086 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, output_types
[1]);
6087 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6088 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_PRIMARYOUTPUT
, 1);
6089 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6090 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6091 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6092 ok(media_type
== output_types
[1], "Unexpected pointer.\n");
6093 IMFMediaType_Release(media_type
);
6094 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6095 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6096 ok(media_type
== output_types
[1], "Unexpected pointer.\n");
6097 IMFMediaType_Release(media_type
);
6098 hr
= pMFGetTopoNodeCurrentType(node
, 1, FALSE
, &media_type
);
6099 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6100 ok(media_type
== output_types
[1], "Unexpected pointer.\n");
6101 IMFMediaType_Release(media_type
);
6103 /* Input type returned, if set. */
6104 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, input_types
[0]);
6105 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6106 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6107 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6108 ok(media_type
== input_types
[0], "Unexpected pointer.\n");
6109 IMFMediaType_Release(media_type
);
6110 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6111 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6112 ok(media_type
== input_types
[0], "Unexpected pointer.\n");
6113 IMFMediaType_Release(media_type
);
6115 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
6116 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6117 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, NULL
);
6118 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6119 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, NULL
);
6120 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
6121 ref
= IMFTopologyNode_Release(node
);
6122 ok(ref
== 0, "Release returned %ld\n", ref
);
6126 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
6127 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
6128 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6129 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
6130 hr
= pMFGetTopoNodeCurrentType(node
, 1, TRUE
, &media_type
);
6131 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6132 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6133 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6135 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)input_descriptor
);
6136 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6137 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6138 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
6140 hr
= IMFMediaTypeHandler_SetCurrentMediaType(input_handler
, output_types
[0]);
6141 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6142 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6143 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6144 ok(media_type
== output_types
[0], "Unexpected pointer.\n");
6145 IMFMediaType_Release(media_type
);
6147 ref
= IMFTopologyNode_Release(node
);
6148 ok(ref
== 0, "Release returned %ld\n", ref
);
6152 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
6153 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
6154 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6155 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6156 hr
= pMFGetTopoNodeCurrentType(node
, 1, FALSE
, &media_type
);
6157 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6158 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6159 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6161 stream_sink
.handler
= output_handler
;
6162 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)&stream_sink
.IMFStreamSink_iface
);
6163 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6164 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6165 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
6167 hr
= IMFMediaTypeHandler_SetCurrentMediaType(output_handler
, input_types
[0]);
6168 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6169 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6170 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6171 ok(media_type
== input_types
[0], "Unexpected pointer.\n");
6172 IMFMediaType_Release(media_type
);
6174 ref
= IMFTopologyNode_Release(node
);
6175 ok(ref
== 0, "Release returned %ld\n", ref
);
6178 /* Transform node. */
6179 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
6180 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
6181 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6182 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6183 hr
= pMFGetTopoNodeCurrentType(node
, 1, TRUE
, &media_type
);
6184 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6185 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6186 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6187 hr
= pMFGetTopoNodeCurrentType(node
, 1, FALSE
, &media_type
);
6188 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
6190 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)transform
);
6191 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6192 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6193 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6194 hr
= pMFGetTopoNodeCurrentType(node
, 1, TRUE
, &media_type
);
6195 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6196 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6197 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6198 hr
= pMFGetTopoNodeCurrentType(node
, 1, FALSE
, &media_type
);
6199 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
6201 hr
= IMFTransform_SetInputType(transform
, 0, input_types
[0], 0);
6202 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6203 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6204 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6205 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
6206 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6207 hr
= IMFMediaType_IsEqual(media_type
, input_types
[0], &flags
);
6208 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6209 IMFMediaType_Release(media_type
);
6211 hr
= IMFTransform_SetOutputType(transform
, 0, output_types
[0], 0);
6212 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6213 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
6214 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6215 hr
= IMFMediaType_IsEqual(media_type
, output_types
[0], &flags
);
6216 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6217 IMFMediaType_Release(media_type
);
6219 ref
= IMFTopologyNode_Release(node
);
6220 ok(ref
== 0, "Release returned %ld\n", ref
);
6223 ref
= IMFTransform_Release(transform
);
6224 ok(ref
== 0, "Release returned %ld\n", ref
);
6226 IMFMediaTypeHandler_Release(input_handler
);
6227 IMFMediaTypeHandler_Release(output_handler
);
6228 ref
= IMFStreamDescriptor_Release(input_descriptor
);
6229 ok(ref
== 0, "Release returned %ld\n", ref
);
6230 ref
= IMFStreamDescriptor_Release(output_descriptor
);
6231 ok(ref
== 0, "Release returned %ld\n", ref
);
6233 ref
= IMFMediaType_Release(input_types
[0]);
6234 ok(ref
== 0, "Release returned %ld\n", ref
);
6235 ref
= IMFMediaType_Release(input_types
[1]);
6236 ok(ref
== 0, "Release returned %ld\n", ref
);
6237 ref
= IMFMediaType_Release(output_types
[0]);
6238 ok(ref
== 0, "Release returned %ld\n", ref
);
6239 ref
= IMFMediaType_Release(output_types
[1]);
6240 ok(ref
== 0, "Release returned %ld\n", ref
);
6245 static void init_functions(void)
6247 HMODULE mod
= GetModuleHandleA("mf.dll");
6249 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
6250 X(MFCreateSampleCopierMFT
);
6251 X(MFGetTopoNodeCurrentType
);
6255 static void test_MFRequireProtectedEnvironment(void)
6257 IMFPresentationDescriptor
*pd
;
6258 IMFMediaType
*mediatype
;
6259 IMFStreamDescriptor
*sd
;
6263 hr
= MFCreateMediaType(&mediatype
);
6264 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6266 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
6267 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
6269 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
6270 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
6272 hr
= IMFPresentationDescriptor_SelectStream(pd
, 0);
6273 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6275 hr
= MFRequireProtectedEnvironment(pd
);
6276 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
6278 hr
= IMFStreamDescriptor_SetUINT32(sd
, &MF_SD_PROTECTED
, 1);
6279 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6281 hr
= MFRequireProtectedEnvironment(pd
);
6282 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6284 hr
= IMFPresentationDescriptor_DeselectStream(pd
, 0);
6285 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6287 hr
= MFRequireProtectedEnvironment(pd
);
6288 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6290 ref
= IMFPresentationDescriptor_Release(pd
);
6291 ok(ref
== 0, "Release returned %ld\n", ref
);
6292 ref
= IMFStreamDescriptor_Release(sd
);
6293 ok(ref
== 0, "Release returned %ld\n", ref
);
6294 ref
= IMFMediaType_Release(mediatype
);
6295 ok(ref
== 0, "Release returned %ld\n", ref
);
6298 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
6300 IMFMediaBuffer
*media_buffer
;
6307 hr
= MFCreateSample(&sample
);
6308 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
6309 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
6310 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
6311 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
6312 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
6313 ok(length
== 0, "got length %lu\n", length
);
6314 if (!data
) memset(buffer
, 0xcd, size
);
6315 else memcpy(buffer
, data
, size
);
6316 hr
= IMFMediaBuffer_Unlock(media_buffer
);
6317 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
6318 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
6319 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
6320 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
6321 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
6322 ret
= IMFMediaBuffer_Release(media_buffer
);
6323 ok(ret
== 1, "Release returned %lu\n", ret
);
6328 #define check_sample(a, b, c) check_sample_(__LINE__, a, b, c)
6329 static void check_sample_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
)
6331 IMFMediaBuffer
*media_buffer
;
6337 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
6338 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
6339 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
6340 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
6341 ok_(__FILE__
, line
)(!memcmp(expect_buf
, buffer
, length
), "unexpected buffer data\n");
6342 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
6343 hr
= IMFMediaBuffer_Unlock(media_buffer
);
6344 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
6345 ret
= IMFMediaBuffer_Release(media_buffer
);
6346 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
6349 #define check_sample_rgb32(a, b, c) check_sample_rgb32_(__LINE__, a, b, c)
6350 static void check_sample_rgb32_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
)
6352 DWORD i
, length
, diff
= 0, max_diff
;
6353 IMFMediaBuffer
*media_buffer
;
6358 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
6359 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
6360 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
6361 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
6363 /* check that buffer values are "close" enough, there's some pretty big
6364 * differences with the color converter between ffmpeg and native.
6366 for (i
= 0; i
< length
; i
++)
6368 if (i
% 4 == 3) continue; /* ignore alpha diff */
6369 diff
+= abs((int)expect_buf
[i
] - (int)buffer
[i
]);
6371 max_diff
= length
* 3 * 256;
6372 ok_(__FILE__
, line
)(diff
* 100 / max_diff
== 0, "unexpected buffer data\n");
6374 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
6375 hr
= IMFMediaBuffer_Unlock(media_buffer
);
6376 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
6377 ret
= IMFMediaBuffer_Release(media_buffer
);
6378 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
6381 #define check_sample_pcm16(a, b, c, d) check_sample_pcm16_(__LINE__, a, b, c, d)
6382 static void check_sample_pcm16_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
, BOOL todo
)
6384 IMFMediaBuffer
*media_buffer
;
6390 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
6391 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
6392 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
6393 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
6395 /* check that buffer values are close enough, there's some differences in
6396 * the output of audio DSP between 32bit and 64bit implementation
6398 for (i
= 0; i
< length
; i
+= 2)
6400 DWORD expect
= *(INT16
*)(expect_buf
+ i
), value
= *(INT16
*)(buffer
+ i
);
6401 if (expect
- value
+ 512 > 1024) break;
6404 todo_wine_if(todo
&& i
< length
/ 2)
6405 ok_(__FILE__
, line
)(i
== length
, "unexpected buffer data\n");
6407 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
6408 hr
= IMFMediaBuffer_Unlock(media_buffer
);
6409 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
6410 ret
= IMFMediaBuffer_Release(media_buffer
);
6411 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
6414 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
6415 static const ULONG wmaenc_block_size
= 1487;
6416 static const ULONG wmadec_block_size
= 0x2000;
6418 static void test_wma_encoder(void)
6420 const GUID transform_inputs
[] =
6423 MFAudioFormat_Float
,
6425 const GUID transform_outputs
[] =
6427 MFAudioFormat_WMAudioV8
,
6428 MFAudioFormat_WMAudioV9
,
6429 MFAudioFormat_WMAudio_Lossless
,
6431 const GUID dmo_inputs
[] =
6435 const GUID dmo_outputs
[] =
6437 MEDIASUBTYPE_WMAUDIO2
,
6438 MEDIASUBTYPE_WMAUDIO3
,
6439 MEDIASUBTYPE_WMAUDIO_LOSSLESS
,
6442 static const struct attribute_desc input_type_desc
[] =
6444 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6445 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6446 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6447 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6448 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6449 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
6450 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
6453 const struct attribute_desc output_type_desc
[] =
6455 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6456 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6457 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6458 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6459 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
6460 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
6461 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
6465 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
6466 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
6467 ULONG audio_data_len
, wmaenc_data_len
;
6468 const BYTE
*audio_data
, *wmaenc_data
;
6469 MFT_OUTPUT_STREAM_INFO output_info
;
6470 MFT_INPUT_STREAM_INFO input_info
;
6471 MFT_OUTPUT_DATA_BUFFER output
;
6472 WCHAR output_path
[MAX_PATH
];
6473 IMFMediaType
*media_type
;
6474 IMFTransform
*transform
;
6475 DWORD status
, length
;
6484 hr
= CoInitialize(NULL
);
6485 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6487 if (!create_transform(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, L
"WMAudio Encoder MFT", &MFMediaType_Audio
,
6488 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6489 &transform
, &CLSID_CWMAEncMediaObject
, &class_id
))
6492 check_dmo(&class_id
, L
"WMAudio Encoder DMO", &MEDIATYPE_Audio
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
6493 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
6495 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6496 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6497 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6498 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
6500 hr
= MFCreateMediaType(&media_type
);
6501 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6502 init_media_type(media_type
, input_type_desc
, -1);
6503 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6504 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6505 init_media_type(media_type
, output_type_desc
, -1);
6506 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6507 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6508 ret
= IMFMediaType_Release(media_type
);
6509 ok(ret
== 0, "Release returned %lu\n", ret
);
6511 memset(&input_info
, 0xcd, sizeof(input_info
));
6512 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6513 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6514 ok(input_info
.hnsMaxLatency
== 19969161, "got hnsMaxLatency %s\n",
6515 wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6516 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
6517 ok(input_info
.cbSize
== 8, "got cbSize %lu\n", input_info
.cbSize
);
6518 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6519 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6521 memset(&output_info
, 0xcd, sizeof(output_info
));
6522 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6523 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6524 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6525 ok(output_info
.cbSize
== wmaenc_block_size
, "got cbSize %#lx\n", output_info
.cbSize
);
6526 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6528 resource
= FindResourceW(NULL
, L
"audiodata.bin", (const WCHAR
*)RT_RCDATA
);
6529 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6530 audio_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6531 audio_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6532 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
6534 sample
= create_sample(audio_data
, audio_data_len
);
6535 hr
= IMFSample_SetSampleTime(sample
, 0);
6536 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
6537 hr
= IMFSample_SetSampleDuration(sample
, 10000000);
6538 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
6539 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6540 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6541 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6542 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6543 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6544 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6545 ref
= IMFSample_Release(sample
);
6546 ok(ref
<= 1, "Release returned %ld\n", ref
);
6548 status
= 0xdeadbeef;
6549 sample
= create_sample(NULL
, output_info
.cbSize
);
6550 memset(&output
, 0, sizeof(output
));
6551 output
.pSample
= sample
;
6553 resource
= FindResourceW(NULL
, L
"wmaencdata.bin", (const WCHAR
*)RT_RCDATA
);
6554 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6555 wmaenc_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6556 wmaenc_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6557 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
6559 /* and generate a new one as well in a temporary directory */
6560 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
6561 lstrcatW(output_path
, L
"wmaencdata.bin");
6562 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
6563 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
6566 while (SUCCEEDED(hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
)))
6568 winetest_push_context("%lu", i
);
6569 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6570 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6571 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
6572 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)) /* win7 */,
6573 "got dwStatus %#lx\n", output
.dwStatus
);
6574 ok(status
== 0, "got status %#lx\n", status
);
6575 hr
= IMFSample_GetTotalLength(sample
, &length
);
6576 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6577 ok(length
== wmaenc_block_size
, "got length %lu\n", length
);
6578 ok(wmaenc_data_len
> i
* wmaenc_block_size
, "got %lu blocks\n", i
);
6579 check_sample(sample
, wmaenc_data
+ i
* wmaenc_block_size
, output_file
);
6580 winetest_pop_context();
6584 trace("created %s\n", debugstr_w(output_path
));
6585 CloseHandle(output_file
);
6587 ret
= IMFSample_Release(sample
);
6588 ok(ret
== 0, "Release returned %lu\n", ret
);
6590 status
= 0xdeadbeef;
6591 sample
= create_sample(NULL
, output_info
.cbSize
);
6592 memset(&output
, 0, sizeof(output
));
6593 output
.pSample
= sample
;
6594 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6595 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6596 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6597 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6598 ok(status
== 0, "got status %#lx\n", status
);
6599 hr
= IMFSample_GetTotalLength(sample
, &length
);
6600 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6601 ok(length
== 0, "got length %lu\n", length
);
6602 ret
= IMFSample_Release(sample
);
6603 ok(ret
== 0, "Release returned %lu\n", ret
);
6605 ret
= IMFTransform_Release(transform
);
6606 ok(ret
== 0, "Release returned %lu\n", ret
);
6612 static void test_wma_decoder(void)
6614 const GUID transform_inputs
[] =
6616 MEDIASUBTYPE_MSAUDIO1
,
6617 MFAudioFormat_WMAudioV8
,
6618 MFAudioFormat_WMAudioV9
,
6619 MFAudioFormat_WMAudio_Lossless
,
6621 const GUID transform_outputs
[] =
6624 MFAudioFormat_Float
,
6626 const GUID dmo_inputs
[] =
6628 MEDIASUBTYPE_MSAUDIO1
,
6629 MEDIASUBTYPE_WMAUDIO2
,
6630 MEDIASUBTYPE_WMAUDIO3
,
6631 MEDIASUBTYPE_WMAUDIO_LOSSLESS
,
6633 const GUID dmo_outputs
[] =
6636 MEDIASUBTYPE_IEEE_FLOAT
,
6639 static const media_type_desc expect_available_inputs
[] =
6642 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6643 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
6644 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6647 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6648 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6649 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6652 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6653 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
6654 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6657 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6658 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
6659 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6662 static const media_type_desc expect_available_outputs
[] =
6665 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6666 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6667 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6668 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6669 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6670 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
6671 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
6672 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6673 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6674 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6677 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6678 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6679 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6680 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6681 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6682 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6683 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6684 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6685 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6686 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6690 const struct attribute_desc input_type_desc
[] =
6692 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6693 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6694 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
6695 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
6696 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6697 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6700 static const struct attribute_desc output_type_desc
[] =
6702 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6703 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6704 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6705 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6706 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6707 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6708 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6712 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
6713 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
6714 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
6715 ULONG wmadec_data_len
, wmaenc_data_len
;
6716 const BYTE
*wmadec_data
, *wmaenc_data
;
6717 MFT_OUTPUT_STREAM_INFO output_info
;
6718 MFT_OUTPUT_DATA_BUFFER outputs
[2];
6719 MFT_INPUT_STREAM_INFO input_info
;
6720 MFT_OUTPUT_DATA_BUFFER output
;
6721 DWORD status
, flags
, length
;
6722 WCHAR output_path
[MAX_PATH
];
6723 IMediaObject
*media_object
;
6724 IPropertyBag
*property_bag
;
6725 IMFMediaType
*media_type
;
6726 IMFTransform
*transform
;
6727 LONGLONG time
, duration
;
6736 hr
= CoInitialize(NULL
);
6737 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6739 if (!create_transform(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, L
"WMAudio Decoder MFT", &MFMediaType_Audio
,
6740 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6741 &transform
, &CLSID_CWMADecMediaObject
, &class_id
))
6744 check_dmo(&class_id
, L
"WMAudio Decoder DMO", &MEDIATYPE_Audio
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
6745 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
6747 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6748 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6750 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6751 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
6753 /* check default media types */
6755 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6756 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6757 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6758 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6759 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6760 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6763 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6765 winetest_push_context("in %lu", i
);
6766 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6767 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6768 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6769 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6770 ret
= IMFMediaType_Release(media_type
);
6771 ok(ret
== 0, "Release returned %lu\n", ret
);
6772 winetest_pop_context();
6775 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6777 ok(i
== 4, "%lu input media types\n", i
);
6779 /* setting output media type first doesn't work */
6781 hr
= MFCreateMediaType(&media_type
);
6782 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6783 init_media_type(media_type
, output_type_desc
, -1);
6784 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6785 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
6786 ret
= IMFMediaType_Release(media_type
);
6787 ok(ret
== 0, "Release returned %lu\n", ret
);
6789 /* check required input media type attributes */
6791 hr
= MFCreateMediaType(&media_type
);
6792 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6793 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6794 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6795 init_media_type(media_type
, input_type_desc
, 1);
6796 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6797 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6798 init_media_type(media_type
, input_type_desc
, 2);
6799 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
6801 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6802 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6803 init_media_type(media_type
, input_type_desc
, i
+ 1);
6805 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6806 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6807 ret
= IMFMediaType_Release(media_type
);
6808 ok(ret
== 0, "Release returned %lu\n", ret
);
6810 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6811 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6812 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6813 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6815 /* check new output media types */
6818 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6820 winetest_push_context("out %lu", i
);
6821 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6822 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6823 ret
= IMFMediaType_Release(media_type
);
6824 ok(ret
== 0, "Release returned %lu\n", ret
);
6825 winetest_pop_context();
6827 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6828 ok(i
== 2, "%lu output media types\n", i
);
6830 /* check required output media type attributes */
6832 hr
= MFCreateMediaType(&media_type
);
6833 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6834 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6835 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6836 init_media_type(media_type
, output_type_desc
, 1);
6837 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6838 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6839 init_media_type(media_type
, output_type_desc
, 2);
6840 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
6842 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6843 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
6844 init_media_type(media_type
, output_type_desc
, i
+ 1);
6846 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6847 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6848 ret
= IMFMediaType_Release(media_type
);
6849 ok(ret
== 0, "Release returned %lu\n", ret
);
6851 memset(&input_info
, 0xcd, sizeof(input_info
));
6852 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6853 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6854 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6855 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
6856 ok(input_info
.cbSize
== wmaenc_block_size
, "got cbSize %lu\n", input_info
.cbSize
);
6857 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6858 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6860 memset(&output_info
, 0xcd, sizeof(output_info
));
6861 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6862 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6863 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6865 ok(output_info
.cbSize
== 0, "got cbSize %#lx\n", output_info
.cbSize
);
6866 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6868 /* MF_MT_AUDIO_AVG_BYTES_PER_SECOND isn't required by SetInputType, but is needed for the transform to work */
6870 hr
= MFCreateMediaType(&media_type
);
6871 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6872 init_media_type(media_type
, input_type_desc
, -1);
6873 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003);
6874 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
6875 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6876 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6878 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6879 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6881 init_media_type(media_type
, output_type_desc
, -1);
6882 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6883 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6884 ret
= IMFMediaType_Release(media_type
);
6885 ok(ret
== 0, "Release returned %lu\n", ret
);
6887 memset(&output_info
, 0xcd, sizeof(output_info
));
6888 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6889 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6890 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6891 ok(output_info
.cbSize
== wmadec_block_size
, "got cbSize %#lx\n", output_info
.cbSize
);
6892 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6894 resource
= FindResourceW(NULL
, L
"wmaencdata.bin", (const WCHAR
*)RT_RCDATA
);
6895 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6896 wmaenc_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6897 wmaenc_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6898 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
6900 sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
6901 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6902 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6903 ret
= IMFSample_Release(sample
);
6904 ok(ret
== 0, "Release returned %lu\n", ret
);
6905 sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
6906 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6907 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6908 ret
= IMFSample_Release(sample
);
6909 ok(ret
== 0, "Release returned %lu\n", ret
);
6910 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
6911 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6912 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6913 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6914 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6915 ret
= IMFSample_Release(sample
);
6916 ok(ret
== 1, "Release returned %lu\n", ret
);
6918 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
6919 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
6921 status
= 0xdeadbeef;
6922 memset(&output
, 0, sizeof(output
));
6923 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6924 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6925 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6926 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6927 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6928 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6929 "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
);
6933 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
6934 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6935 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6936 ret
= IMFSample_Release(sample
);
6937 ok(ret
== 0, "Release returned %lu\n", ret
);
6939 status
= 0xdeadbeef;
6940 memset(&output
, 0, sizeof(output
));
6941 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6942 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6943 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6944 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6945 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6946 "got dwStatus %#lx\n", output
.dwStatus
);
6947 ok(status
== 0, "got status %#lx\n", status
);
6949 status
= 0xdeadbeef;
6950 memset(&output
, 0, sizeof(output
));
6951 output_info
.cbSize
= wmadec_block_size
;
6952 sample
= create_sample(NULL
, output_info
.cbSize
);
6953 outputs
[0].pSample
= sample
;
6954 sample
= create_sample(NULL
, output_info
.cbSize
);
6955 outputs
[1].pSample
= sample
;
6956 hr
= IMFTransform_ProcessOutput(transform
, 0, 2, outputs
, &status
);
6957 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
6958 ref
= IMFSample_Release(outputs
[0].pSample
);
6959 ok(ref
== 0, "Release returned %ld\n", ref
);
6960 ref
= IMFSample_Release(outputs
[1].pSample
);
6961 ok(ref
== 0, "Release returned %ld\n", ref
);
6963 resource
= FindResourceW(NULL
, L
"wmadecdata.bin", (const WCHAR
*)RT_RCDATA
);
6964 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6965 wmadec_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6966 wmadec_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6967 ok(wmadec_data_len
== wmadec_block_size
* 7 / 2, "got length %lu\n", wmadec_data_len
);
6969 /* and generate a new one as well in a temporary directory */
6970 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
6971 lstrcatW(output_path
, L
"wmadecdata.bin");
6972 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
6973 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
6975 status
= 0xdeadbeef;
6976 output_info
.cbSize
= wmadec_block_size
;
6977 sample
= create_sample(NULL
, output_info
.cbSize
);
6978 memset(&output
, 0, sizeof(output
));
6979 output
.pSample
= sample
;
6980 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6982 for (i
= 0; i
< 4; ++i
)
6984 winetest_push_context("%lu", i
);
6986 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6987 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6988 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| output
.dwStatus
== 0 ||
6989 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7) || output
.dwStatus
== 7) /* Win7 */,
6990 "got dwStatus %#lx\n", output
.dwStatus
);
6991 ok(status
== 0, "got status %#lx\n", status
);
6993 hr
= IMFSample_GetUINT32(sample
, &MFSampleExtension_CleanPoint
, &value
);
6994 ok(hr
== S_OK
, "GetUINT32 MFSampleExtension_CleanPoint returned %#lx\n", hr
);
6995 ok(value
== 1, "got MFSampleExtension_CleanPoint %u\n", value
);
6996 hr
= IMFSample_GetTotalLength(sample
, &length
);
6997 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6999 hr
= IMFSample_GetSampleFlags(sample
, &flags
);
7000 ok(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
7001 ok(flags
== 0, "got flags %#lx\n", flags
);
7003 hr
= IMFSample_GetSampleTime(sample
, &time
);
7004 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7005 ok(time
== i
* 928798, "got time %I64d\n", time
);
7006 duration
= 0xdeadbeef;
7007 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
7008 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7009 if (output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
7010 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)))
7012 ok(length
== wmadec_block_size
, "got length %lu\n", length
);
7013 ok(duration
== 928798, "got duration %I64d\n", duration
);
7014 check_sample_pcm16(sample
, wmadec_data
, output_file
, TRUE
);
7015 wmadec_data
+= wmadec_block_size
;
7016 wmadec_data_len
-= wmadec_block_size
;
7020 /* FFmpeg doesn't seem to decode WMA buffers in the same way as native */
7022 ok(length
== wmadec_block_size
/ 2, "got length %lu\n", length
);
7024 ok(duration
== 464399, "got duration %I64d\n", duration
);
7026 if (length
== wmadec_block_size
/ 2)
7027 check_sample_pcm16(sample
, wmadec_data
, output_file
, FALSE
);
7028 wmadec_data
+= length
;
7029 wmadec_data_len
-= length
;
7031 ret
= IMFSample_Release(sample
);
7032 ok(ret
== 0, "Release returned %lu\n", ret
);
7034 status
= 0xdeadbeef;
7035 sample
= create_sample(NULL
, output_info
.cbSize
);
7036 memset(&output
, 0, sizeof(output
));
7037 output
.pSample
= sample
;
7038 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7040 winetest_pop_context();
7042 /* some FFmpeg version request more input to complete decoding */
7043 if (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
&& i
== 2) break;
7046 ok(wmadec_data_len
== 0, "missing %#lx bytes\n", wmadec_data_len
);
7048 trace("created %s\n", debugstr_w(output_path
));
7049 CloseHandle(output_file
);
7051 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7052 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
7053 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7054 ok(status
== 0, "got status %#lx\n", status
);
7055 ret
= IMFSample_Release(sample
);
7056 ok(ret
== 0, "Release returned %lu\n", ret
);
7058 status
= 0xdeadbeef;
7059 sample
= create_sample(NULL
, output_info
.cbSize
);
7060 memset(&output
, 0, sizeof(output
));
7061 output
.pSample
= sample
;
7062 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7063 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7064 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
7065 ok(output
.dwStatus
== 0 ||
7066 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)) /* Win7 */,
7067 "got dwStatus %#lx\n", output
.dwStatus
);
7068 ok(status
== 0, "got status %#lx\n", status
);
7069 hr
= IMFSample_GetTotalLength(sample
, &length
);
7070 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7071 ok(length
== 0, "got length %lu\n", length
);
7072 ret
= IMFSample_Release(sample
);
7073 ok(ret
== 0, "Release returned %lu\n", ret
);
7075 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
7076 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7077 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7079 ret
= IMFTransform_Release(transform
);
7080 ok(ret
== 0, "Release returned %lu\n", ret
);
7081 ret
= IMFSample_Release(sample
);
7082 ok(ret
== 0, "Release returned %lu\n", ret
);
7084 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
7085 (void **)&unknown
);
7086 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
7087 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
7088 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
7089 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
7090 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
7091 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
7092 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
7093 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
7094 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
7096 ok( unknown
!= &outer
, "got outer IUnknown\n" );
7097 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
7098 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
7099 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
7100 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
7102 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
7103 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
7104 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
7105 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
7106 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
7107 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
7109 ref
= IUnknown_Release( tmp_unknown
);
7110 ok( ref
== 1, "Release returned %lu\n", ref
);
7111 ref
= IPropertyBag_Release( property_bag
);
7112 ok( ref
== 1, "Release returned %lu\n", ref
);
7113 ref
= IMediaObject_Release( media_object
);
7114 ok( ref
== 1, "Release returned %lu\n", ref
);
7115 ref
= IMFTransform_Release( transform
);
7116 ok( ref
== 1, "Release returned %lu\n", ref
);
7117 ref
= IUnknown_Release( unknown
);
7118 ok( ref
== 0, "Release returned %lu\n", ref
);
7124 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
7125 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
7127 const BYTE
*sample_data
;
7129 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
7130 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
7131 sample_data
= *h264_buf
;
7136 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
7142 return create_sample(sample_data
, *h264_buf
- sample_data
);
7145 static void test_h264_decoder(void)
7147 const GUID transform_inputs
[] =
7150 MFVideoFormat_H264_ES
,
7152 const GUID transform_outputs
[] =
7160 static const media_type_desc default_inputs
[] =
7163 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7164 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
7167 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7168 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
7171 static const DWORD input_width
= 120, input_height
= 248;
7172 const media_type_desc default_outputs
[] =
7175 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7176 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
7177 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7178 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
7179 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
7180 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7181 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7182 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7183 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7184 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
7185 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7188 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7189 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
7190 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7191 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
7192 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
7193 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7194 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7195 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7196 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7197 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
7198 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7201 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7202 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
7203 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7204 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
7205 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
7206 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7207 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7208 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7209 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7210 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
7211 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7214 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7215 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
7216 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7217 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
7218 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
7219 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7220 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7221 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7222 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7223 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
7224 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7227 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7228 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
7229 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7230 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
7231 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
* 2),
7232 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7233 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7234 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7235 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7236 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 2),
7237 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7240 const struct attribute_desc input_type_desc
[] =
7242 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7243 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
7244 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7247 const struct attribute_desc minimal_output_type_desc
[] =
7249 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7250 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
7251 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7254 const struct attribute_desc output_type_desc
[] =
7256 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7257 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
7258 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
7259 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7260 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
7261 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
7262 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
7263 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
7266 static const struct attribute_desc new_output_type_desc
[] =
7268 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7269 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
7270 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
7271 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
7272 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
7275 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
7276 static const DWORD actual_width
= 96, actual_height
= 96;
7277 const media_type_desc actual_outputs
[] =
7280 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7281 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
7282 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7283 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7284 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7285 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
7286 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
7287 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7288 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7289 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7290 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7291 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7294 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7295 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
7296 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7297 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7298 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7299 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
7300 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
7301 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7302 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7303 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7304 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7305 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7308 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7309 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
7310 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7311 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7312 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7313 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
7314 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
7315 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7316 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7317 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7318 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7319 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7322 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7323 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
7324 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7325 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7326 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7327 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
7328 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
7329 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7330 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7331 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7332 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7333 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7336 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7337 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
7338 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
7339 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
7340 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7341 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
7342 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
7343 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
7344 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
7345 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7346 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7347 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7351 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
7352 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
7353 const BYTE
*h264_encoded_data
, *nv12_frame_data
, *i420_frame_data
;
7354 ULONG h264_encoded_data_len
, nv12_frame_len
, i420_frame_len
;
7355 DWORD input_id
, output_id
, input_count
, output_count
;
7356 MFT_OUTPUT_STREAM_INFO output_info
;
7357 MFT_INPUT_STREAM_INFO input_info
;
7358 MFT_OUTPUT_DATA_BUFFER output
;
7359 IMFMediaBuffer
*media_buffer
;
7360 DWORD status
, length
, count
;
7361 WCHAR output_path
[MAX_PATH
];
7362 IMFAttributes
*attributes
;
7363 IMFMediaType
*media_type
;
7364 LONGLONG time
, duration
;
7365 IMFTransform
*transform
;
7366 ULONG i
, ret
, flags
;
7375 hr
= CoInitialize(NULL
);
7376 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
7378 if (!create_transform(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, L
"Microsoft H264 Video Decoder MFT", &MFMediaType_Video
,
7379 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
7380 &transform
, &CLSID_MSH264DecoderMFT
, &class_id
))
7383 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
7384 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
7385 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
7386 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
7387 ret
= IMFAttributes_Release(attributes
);
7389 ok(ret
== 1, "Release returned %ld\n", ret
);
7391 /* no output type is available before an input type is set */
7393 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
7394 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
7395 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7396 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputCurrentType returned %#lx\n", hr
);
7398 /* setting output media type first doesn't work */
7400 hr
= MFCreateMediaType(&media_type
);
7401 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7402 init_media_type(media_type
, default_outputs
[0], -1);
7403 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7404 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
7405 ret
= IMFMediaType_Release(media_type
);
7406 ok(ret
== 0, "Release returned %lu\n", ret
);
7408 /* check available input types */
7410 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
7411 memset(&input_info
, 0xcd, sizeof(input_info
));
7412 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7414 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
7416 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
7418 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
7420 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
7422 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
7424 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
7426 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7427 memset(&output_info
, 0xcd, sizeof(output_info
));
7428 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7429 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7430 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7431 ok(output_info
.cbSize
== 1920 * 1088 * 2, "got cbSize %#lx\n", output_info
.cbSize
);
7432 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7435 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
7437 winetest_push_context("in %lu", i
);
7438 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
7439 check_media_type(media_type
, default_inputs
[i
], -1);
7440 ret
= IMFMediaType_Release(media_type
);
7441 ok(ret
== 0, "Release returned %lu\n", ret
);
7442 winetest_pop_context();
7444 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
7445 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
7447 /* check required input media type attributes */
7449 hr
= MFCreateMediaType(&media_type
);
7450 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7451 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7452 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
7453 init_media_type(media_type
, input_type_desc
, 1);
7454 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7456 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
7457 init_media_type(media_type
, input_type_desc
, 2);
7458 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7459 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
7460 init_media_type(media_type
, input_type_desc
, -1);
7461 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7462 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
7463 ret
= IMFMediaType_Release(media_type
);
7464 ok(ret
== 1, "Release returned %lu\n", ret
);
7466 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7467 memset(&output_info
, 0xcd, sizeof(output_info
));
7468 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7469 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7470 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7472 ok(output_info
.cbSize
== input_width
* input_height
* 2, "got cbSize %#lx\n", output_info
.cbSize
);
7473 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7475 /* output types can now be enumerated (though they are actually the same for all input types) */
7478 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7480 winetest_push_context("out %lu", i
);
7481 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7482 check_media_type(media_type
, default_outputs
[i
], -1);
7483 ret
= IMFMediaType_Release(media_type
);
7484 ok(ret
== 0, "Release returned %lu\n", ret
);
7485 winetest_pop_context();
7487 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7488 ok(i
== 5, "%lu output media types\n", i
);
7490 /* check required output media type attributes */
7492 hr
= MFCreateMediaType(&media_type
);
7493 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7494 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7496 ok(hr
== E_INVALIDARG
, "SetOutputType returned %#lx.\n", hr
);
7497 init_media_type(media_type
, minimal_output_type_desc
, 1);
7498 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7500 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
7501 init_media_type(media_type
, minimal_output_type_desc
, 2);
7502 for (i
= 2; i
< ARRAY_SIZE(minimal_output_type_desc
) - 1; ++i
)
7504 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7506 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
7507 init_media_type(media_type
, minimal_output_type_desc
, i
+ 1);
7509 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7510 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7511 init_media_type(media_type
, output_type_desc
, -1);
7512 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7513 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7514 ret
= IMFMediaType_Release(media_type
);
7515 ok(ret
== 1, "Release returned %lu\n", ret
);
7517 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7518 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7519 check_media_type(media_type
, output_type_desc
, -1);
7520 ret
= IMFMediaType_Release(media_type
);
7521 ok(ret
== 0, "Release returned %lu\n", ret
);
7523 /* check that the output media type we've selected don't change the enumeration */
7526 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7528 winetest_push_context("out %lu", i
);
7529 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7530 check_media_type(media_type
, default_outputs
[i
], -1);
7531 ret
= IMFMediaType_Release(media_type
);
7532 ok(ret
== 0, "Release returned %lu\n", ret
);
7533 winetest_pop_context();
7535 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7536 ok(i
== 5, "%lu output media types\n", i
);
7538 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
7539 memset(&input_info
, 0xcd, sizeof(input_info
));
7540 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7541 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
7542 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
7543 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
7544 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
7545 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
7546 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
7548 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7549 memset(&output_info
, 0xcd, sizeof(output_info
));
7550 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7551 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7552 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7554 ok(output_info
.cbSize
== input_width
* input_height
* 2, "got cbSize %#lx\n", output_info
.cbSize
);
7555 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7557 input_count
= output_count
= 0xdeadbeef;
7558 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
7560 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
7562 ok(input_count
== 1, "got input_count %lu\n", input_count
);
7564 ok(output_count
== 1, "got output_count %lu\n", output_count
);
7565 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
7566 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
7568 resource
= FindResourceW(NULL
, L
"h264data.bin", (const WCHAR
*)RT_RCDATA
);
7569 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7570 h264_encoded_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7571 h264_encoded_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7573 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
7574 * IMFTransform_ProcessOutput needs a sample or returns an error */
7577 memset(&output
, 0, sizeof(output
));
7578 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7579 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7580 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7581 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
7582 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7583 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7584 ok(status
== 0, "got status %#lx\n", status
);
7587 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7591 memset(&output
, 0, sizeof(output
));
7592 output
.pSample
= create_sample(NULL
, output_info
.cbSize
);
7593 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7594 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
7595 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7596 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7597 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7598 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7599 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7600 ok(status
== 0, "got status %#lx\n", status
);
7601 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7602 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7603 ok(length
== 0, "got length %lu\n", length
);
7604 ret
= IMFSample_Release(output
.pSample
);
7605 ok(ret
== 0, "Release returned %lu\n", ret
);
7607 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7608 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7609 ret
= IMFSample_Release(sample
);
7610 ok(ret
<= 1, "Release returned %lu\n", ret
);
7611 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7613 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7614 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7615 ret
= IMFSample_Release(sample
);
7616 ok(ret
<= 1, "Release returned %lu\n", ret
);
7617 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7620 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
7621 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
7624 ok(i
== 2, "got %lu iterations\n", i
);
7626 ok(h264_encoded_data_len
== 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
7627 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7628 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7629 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7630 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
,
7631 "got dwStatus %#lx\n", output
.dwStatus
);
7632 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7633 ok(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
7634 "got status %#lx\n", status
);
7635 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7636 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7637 ok(length
== 0, "got length %lu\n", length
);
7638 ret
= IMFSample_Release(output
.pSample
);
7639 ok(ret
== 0, "Release returned %lu\n", ret
);
7641 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7642 memset(&output_info
, 0xcd, sizeof(output_info
));
7643 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7644 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7645 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7646 ok(output_info
.cbSize
== actual_width
* actual_height
* 2, "got cbSize %#lx\n", output_info
.cbSize
);
7647 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7650 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7652 winetest_push_context("out %lu", i
);
7653 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7654 check_media_type(media_type
, actual_outputs
[i
], -1);
7655 ret
= IMFMediaType_Release(media_type
);
7656 ok(ret
== 0, "Release returned %lu\n", ret
);
7657 winetest_pop_context();
7659 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7660 ok(i
== 5, "%lu output media types\n", i
);
7662 /* current output type is still the one we selected */
7663 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7664 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7665 check_media_type(media_type
, output_type_desc
, -1);
7666 hr
= IMFMediaType_GetItemType(media_type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, NULL
);
7667 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetItemType returned %#lx\n", hr
);
7668 ret
= IMFMediaType_Release(media_type
);
7669 ok(ret
== 0, "Release returned %lu\n", ret
);
7671 /* and generate a new one as well in a temporary directory */
7672 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
7673 lstrcatW(output_path
, L
"nv12frame.bin");
7674 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
7675 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
7677 resource
= FindResourceW(NULL
, L
"nv12frame.bin", (const WCHAR
*)RT_RCDATA
);
7678 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7679 nv12_frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7680 nv12_frame_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7681 ok(nv12_frame_len
== actual_width
* actual_height
* 3 / 2, "got frame length %lu\n", nv12_frame_len
);
7684 memset(&output
, 0, sizeof(output
));
7685 output
.pSample
= create_sample(NULL
, nv12_frame_len
);
7686 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7687 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7688 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7689 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7690 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7691 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7692 ok(status
== 0, "got status %#lx\n", status
);
7694 hr
= IMFSample_GetUINT32(sample
, &MFSampleExtension_CleanPoint
, &value
);
7695 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetUINT32 MFSampleExtension_CleanPoint returned %#lx\n", hr
);
7698 hr
= IMFSample_GetBufferCount(output
.pSample
, &count
);
7699 ok(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
7700 ok(count
== 1, "got count %#lx\n", count
);
7703 hr
= IMFSample_GetSampleFlags(output
.pSample
, &flags
);
7704 ok(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
7705 ok(flags
== 0, "got flags %#lx\n", flags
);
7708 hr
= IMFSample_GetSampleTime(output
.pSample
, &time
);
7709 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7710 ok(time
== 0, "got time %I64d\n", time
);
7712 /* doesn't matter what frame rate we've selected, duration is defined by the stream */
7713 duration
= 0xdeadbeef;
7714 hr
= IMFSample_GetSampleDuration(output
.pSample
, &duration
);
7715 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7716 ok(duration
- 333666 <= 2, "got duration %I64d\n", duration
);
7718 /* Win8 and before pad the data with garbage instead of original
7719 * buffer data, make sure it's consistent. */
7720 hr
= IMFSample_ConvertToContiguousBuffer(output
.pSample
, &media_buffer
);
7721 ok(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
7722 hr
= IMFMediaBuffer_Lock(media_buffer
, &data
, NULL
, &length
);
7723 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
7724 ok(length
== nv12_frame_len
, "got length %lu\n", length
);
7726 for (i
= 0; i
< actual_aperture
.Area
.cy
; ++i
)
7728 memset(data
+ actual_width
* i
+ actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7729 memset(data
+ actual_width
* (actual_height
+ i
/ 2) + actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7731 memset(data
+ actual_width
* actual_aperture
.Area
.cy
, 0xcd, (actual_height
- actual_aperture
.Area
.cy
) * actual_width
);
7732 memset(data
+ actual_width
* (actual_height
+ actual_aperture
.Area
.cy
/ 2), 0xcd, (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
);
7734 hr
= IMFMediaBuffer_Unlock(media_buffer
);
7735 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
7736 IMFMediaBuffer_Release(media_buffer
);
7738 check_sample(output
.pSample
, nv12_frame_data
, output_file
);
7740 ret
= IMFSample_Release(output
.pSample
);
7741 ok(ret
== 0, "Release returned %lu\n", ret
);
7743 trace("created %s\n", debugstr_w(output_path
));
7744 CloseHandle(output_file
);
7746 /* we can change it, but only with the correct frame size */
7747 hr
= MFCreateMediaType(&media_type
);
7748 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7749 init_media_type(media_type
, output_type_desc
, -1);
7750 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7751 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
7752 init_media_type(media_type
, new_output_type_desc
, -1);
7753 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7754 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7755 ret
= IMFMediaType_Release(media_type
);
7756 ok(ret
== 1, "Release returned %lu\n", ret
);
7758 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7759 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7760 check_media_type(media_type
, new_output_type_desc
, -1);
7761 hr
= IMFMediaType_GetItemType(media_type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, NULL
);
7762 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetItemType returned %#lx\n", hr
);
7763 ret
= IMFMediaType_Release(media_type
);
7764 ok(ret
== 0, "Release returned %lu\n", ret
);
7767 memset(&output
, 0, sizeof(output
));
7768 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7769 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7771 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7773 while (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
7775 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7776 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7777 ret
= IMFSample_Release(sample
);
7778 ok(ret
<= 1, "Release returned %lu\n", ret
);
7779 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7780 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7781 todo_wine_if(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
7782 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7785 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7786 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7787 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got dwStatus %#lx\n", output
.dwStatus
);
7788 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7789 ok(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
, "got status %#lx\n", status
);
7790 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7791 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7792 ok(length
== 0, "got length %lu\n", length
);
7793 ret
= IMFSample_Release(output
.pSample
);
7794 ok(ret
== 0, "Release returned %lu\n", ret
);
7796 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
7797 lstrcatW(output_path
, L
"i420frame.bin");
7798 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
7799 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
7801 resource
= FindResourceW(NULL
, L
"i420frame.bin", (const WCHAR
*)RT_RCDATA
);
7802 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7803 i420_frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7804 i420_frame_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7805 ok(i420_frame_len
== actual_width
* actual_height
* 3 / 2, "got frame length %lu\n", i420_frame_len
);
7808 memset(&output
, 0, sizeof(output
));
7809 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7810 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7811 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7812 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7813 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7814 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7815 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7816 ok(status
== 0, "got status %#lx\n", status
);
7818 hr
= IMFSample_GetSampleTime(output
.pSample
, &time
);
7819 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7820 todo_wine_if(time
== 1334666) /* when VA-API plugin is used */
7821 ok(time
- 333666 <= 2, "got time %I64d\n", time
);
7823 duration
= 0xdeadbeef;
7824 hr
= IMFSample_GetSampleDuration(output
.pSample
, &duration
);
7825 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7826 ok(duration
- 333666 <= 2, "got duration %I64d\n", duration
);
7828 /* Win8 and before pad the data with garbage instead of original
7829 * buffer data, make sure it's consistent. */
7830 hr
= IMFSample_ConvertToContiguousBuffer(output
.pSample
, &media_buffer
);
7831 ok(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
7832 hr
= IMFMediaBuffer_Lock(media_buffer
, &data
, NULL
, &length
);
7833 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
7834 ok(length
== i420_frame_len
, "got length %lu\n", length
);
7836 for (i
= 0; i
< actual_aperture
.Area
.cy
; ++i
)
7838 memset(data
+ actual_width
* i
+ actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7839 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * i
+ actual_aperture
.Area
.cx
/ 2, 0xcd,
7840 actual_width
/ 2 - actual_aperture
.Area
.cx
/ 2);
7841 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * (actual_height
/ 2 + i
) + actual_aperture
.Area
.cx
/ 2, 0xcd,
7842 actual_width
/ 2 - actual_aperture
.Area
.cx
/ 2);
7844 memset(data
+ actual_width
* actual_aperture
.Area
.cy
, 0xcd, (actual_height
- actual_aperture
.Area
.cy
) * actual_width
);
7845 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * actual_aperture
.Area
.cy
/ 2, 0xcd,
7846 (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
/ 2);
7847 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * (actual_height
/ 2 + actual_aperture
.Area
.cy
/ 2), 0xcd,
7848 (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
/ 2);
7850 hr
= IMFMediaBuffer_Unlock(media_buffer
);
7851 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
7852 IMFMediaBuffer_Release(media_buffer
);
7854 check_sample(output
.pSample
, i420_frame_data
, output_file
);
7856 ret
= IMFSample_Release(output
.pSample
);
7857 ok(ret
== 0, "Release returned %lu\n", ret
);
7859 trace("created %s\n", debugstr_w(output_path
));
7860 CloseHandle(output_file
);
7863 memset(&output
, 0, sizeof(output
));
7864 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7865 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7866 todo_wine_if(hr
== S_OK
) /* when VA-API plugin is used */
7867 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7868 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7869 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7870 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7871 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7872 ok(status
== 0, "got status %#lx\n", status
);
7873 ret
= IMFSample_Release(output
.pSample
);
7874 ok(ret
== 0, "Release returned %lu\n", ret
);
7876 ret
= IMFTransform_Release(transform
);
7877 ok(ret
== 0, "Release returned %lu\n", ret
);
7878 ret
= IMFSample_Release(sample
);
7879 ok(ret
== 0, "Release returned %lu\n", ret
);
7885 static void test_audio_convert(void)
7887 const GUID transform_inputs
[2] =
7890 MFAudioFormat_Float
,
7892 const GUID transform_outputs
[2] =
7895 MFAudioFormat_Float
,
7898 static const media_type_desc expect_available_inputs
[] =
7901 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7902 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7903 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7906 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7907 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7908 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7911 static const media_type_desc expect_available_outputs
[] =
7914 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7915 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7916 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7919 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7920 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7921 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7924 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7925 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7926 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7927 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7928 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
7929 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
7930 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
7931 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7932 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7935 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7936 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7937 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7938 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7939 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
7940 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
7941 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7942 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7943 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7947 static const struct attribute_desc input_type_desc
[] =
7949 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7950 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7951 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7952 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7953 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7954 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
7955 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
7958 const struct attribute_desc output_type_desc
[] =
7960 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7961 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7962 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7963 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7964 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
7965 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
7966 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7970 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
7971 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
7972 static const ULONG audioconv_block_size
= 0x4000;
7973 ULONG audio_data_len
, audioconv_data_len
;
7974 const BYTE
*audio_data
, *audioconv_data
;
7975 MFT_OUTPUT_STREAM_INFO output_info
;
7976 MFT_INPUT_STREAM_INFO input_info
;
7977 MFT_OUTPUT_DATA_BUFFER output
;
7978 WCHAR output_path
[MAX_PATH
];
7979 IMFMediaType
*media_type
;
7980 LONGLONG time
, duration
;
7981 IMFTransform
*transform
;
7982 DWORD length
, status
;
7990 hr
= CoInitialize(NULL
);
7991 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
7993 if (!create_transform(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, L
"Resampler MFT", &MFMediaType_Audio
,
7994 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
7995 &transform
, &CLSID_CResamplerMediaObject
, &class_id
))
7998 check_dmo(&class_id
, L
"Resampler DMO", &MEDIATYPE_Audio
, transform_inputs
, ARRAY_SIZE(transform_inputs
),
7999 transform_outputs
, ARRAY_SIZE(transform_outputs
));
8001 check_interface(transform
, &IID_IMFTransform
, TRUE
);
8002 check_interface(transform
, &IID_IMediaObject
, TRUE
);
8003 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
8004 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
8005 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
8007 /* check default media types */
8009 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8010 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
8011 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8012 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
8015 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
8017 winetest_push_context("out %lu", i
);
8018 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
8019 check_media_type(media_type
, expect_available_outputs
[i
], -1);
8020 ret
= IMFMediaType_Release(media_type
);
8021 ok(ret
== 0, "Release returned %lu\n", ret
);
8022 winetest_pop_context();
8024 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
8025 ok(i
== 4, "%lu output media types\n", i
);
8028 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
8030 winetest_push_context("in %lu", i
);
8031 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
8032 check_media_type(media_type
, expect_available_inputs
[i
], -1);
8033 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8034 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
8035 ret
= IMFMediaType_Release(media_type
);
8036 ok(ret
== 0, "Release returned %lu\n", ret
);
8037 winetest_pop_context();
8039 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
8040 ok(i
== 2, "%lu input media types\n", i
);
8042 /* setting output media type first doesn't work */
8044 hr
= MFCreateMediaType(&media_type
);
8045 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8046 init_media_type(media_type
, output_type_desc
, -1);
8047 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8048 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
8049 ret
= IMFMediaType_Release(media_type
);
8050 ok(ret
== 0, "Release returned %lu\n", ret
);
8052 /* check required input media type attributes */
8054 hr
= MFCreateMediaType(&media_type
);
8055 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8056 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8057 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8058 init_media_type(media_type
, input_type_desc
, 1);
8059 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8060 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8061 init_media_type(media_type
, input_type_desc
, 2);
8062 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
8064 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8065 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
8066 init_media_type(media_type
, input_type_desc
, i
+ 1);
8068 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8069 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
8070 ret
= IMFMediaType_Release(media_type
);
8071 ok(ret
== 0, "Release returned %lu\n", ret
);
8073 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8074 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
8075 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8076 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
8078 /* check new output media types */
8081 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
8083 winetest_push_context("out %lu", i
);
8084 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
8085 check_media_type(media_type
, expect_available_outputs
[i
], -1);
8086 ret
= IMFMediaType_Release(media_type
);
8087 ok(ret
== 0, "Release returned %lu\n", ret
);
8088 winetest_pop_context();
8090 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
8091 ok(i
== 4, "%lu output media types\n", i
);
8093 /* check required output media type attributes */
8095 hr
= MFCreateMediaType(&media_type
);
8096 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8097 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8098 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8099 init_media_type(media_type
, output_type_desc
, 1);
8100 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8101 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8102 init_media_type(media_type
, output_type_desc
, 2);
8103 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
8105 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8106 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
8107 init_media_type(media_type
, output_type_desc
, i
+ 1);
8109 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8110 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
8111 ret
= IMFMediaType_Release(media_type
);
8112 ok(ret
== 0, "Release returned %lu\n", ret
);
8114 memset(&input_info
, 0xcd, sizeof(input_info
));
8115 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8116 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
8117 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
8118 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
8119 ok(input_info
.cbSize
== 8, "got cbSize %lu\n", input_info
.cbSize
);
8120 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
8121 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
8123 memset(&output_info
, 0xcd, sizeof(output_info
));
8124 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8125 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
8126 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
8127 ok(output_info
.cbSize
== 4, "got cbSize %#lx\n", output_info
.cbSize
);
8128 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
8130 resource
= FindResourceW(NULL
, L
"audiodata.bin", (const WCHAR
*)RT_RCDATA
);
8131 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8132 audio_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8133 audio_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8134 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
8136 sample
= create_sample(audio_data
, audio_data_len
);
8137 hr
= IMFSample_SetSampleTime(sample
, 0);
8138 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
8139 hr
= IMFSample_SetSampleDuration(sample
, 10000000);
8140 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
8141 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
8142 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
8143 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
8144 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
8145 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
8146 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
8147 ret
= IMFSample_Release(sample
);
8148 ok(ret
<= 1, "Release returned %ld\n", ret
);
8150 status
= 0xdeadbeef;
8151 sample
= create_sample(NULL
, audioconv_block_size
);
8152 memset(&output
, 0, sizeof(output
));
8153 output
.pSample
= sample
;
8155 resource
= FindResourceW(NULL
, L
"audioconvdata.bin", (const WCHAR
*)RT_RCDATA
);
8156 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8157 audioconv_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8158 audioconv_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8159 ok(audioconv_data_len
== 179924, "got length %lu\n", audioconv_data_len
);
8161 /* and generate a new one as well in a temporary directory */
8162 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
8163 lstrcatW(output_path
, L
"audioconvdata.bin");
8164 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
8165 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
8168 while (SUCCEEDED(hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
)))
8170 winetest_push_context("%lu", i
);
8171 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
8172 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8173 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| output
.dwStatus
== 0 ||
8174 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|6) || output
.dwStatus
== 6) /* win7 */,
8175 "got dwStatus %#lx\n", output
.dwStatus
);
8176 ok(status
== 0, "got status %#lx\n", status
);
8177 if (!(output
.dwStatus
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
))
8179 winetest_pop_context();
8183 hr
= IMFSample_GetSampleTime(sample
, &time
);
8184 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
8185 ok(time
== i
* 928798, "got time %I64d\n", time
);
8186 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
8187 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
8188 ok(duration
== 928798, "got duration %I64d\n", duration
);
8189 hr
= IMFSample_GetTotalLength(sample
, &length
);
8190 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8191 ok(length
== audioconv_block_size
, "got length %lu\n", length
);
8192 ok(audioconv_data_len
> audioconv_block_size
, "got remaining length %lu\n", audioconv_data_len
);
8193 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
8194 audioconv_data_len
-= audioconv_block_size
;
8195 audioconv_data
+= audioconv_block_size
;
8197 winetest_pop_context();
8201 hr
= IMFSample_GetSampleTime(sample
, &time
);
8202 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
8203 ok(time
== i
* 928798, "got time %I64d\n", time
);
8204 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
8205 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
8207 ok(duration
== 897506, "got duration %I64d\n", duration
);
8208 hr
= IMFSample_GetTotalLength(sample
, &length
);
8209 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8211 ok(length
== 15832, "got length %lu\n", length
);
8212 ok(audioconv_data_len
== 16084, "got remaining length %lu\n", audioconv_data_len
);
8213 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
8214 audioconv_data_len
-= length
;
8215 audioconv_data
+= length
;
8217 memset(&output
, 0, sizeof(output
));
8218 output
.pSample
= sample
;
8219 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8221 ok(hr
== S_OK
|| broken(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
) /* win7 */, "ProcessOutput returned %#lx\n", hr
);
8222 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8224 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| broken(output
.dwStatus
== 0) /* win7 */,
8225 "got dwStatus %#lx\n", output
.dwStatus
);
8226 ok(status
== 0, "got status %#lx\n", status
);
8230 hr
= IMFSample_GetSampleTime(sample
, &time
);
8231 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
8233 ok(time
== 10185486, "got time %I64d\n", time
);
8234 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
8235 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
8237 ok(duration
== 14286, "got duration %I64d\n", duration
);
8238 hr
= IMFSample_GetTotalLength(sample
, &length
);
8239 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8241 ok(length
== audioconv_data_len
, "got length %lu\n", length
);
8242 if (length
== audioconv_data_len
)
8243 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
8246 trace("created %s\n", debugstr_w(output_path
));
8247 CloseHandle(output_file
);
8249 ret
= IMFSample_Release(sample
);
8250 ok(ret
== 0, "Release returned %lu\n", ret
);
8252 status
= 0xdeadbeef;
8253 sample
= create_sample(NULL
, audioconv_block_size
);
8254 memset(&output
, 0, sizeof(output
));
8255 output
.pSample
= sample
;
8256 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8257 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
8258 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8259 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
8260 ok(status
== 0, "got status %#lx\n", status
);
8261 hr
= IMFSample_GetTotalLength(sample
, &length
);
8262 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8263 ok(length
== 0, "got length %lu\n", length
);
8264 ret
= IMFSample_Release(sample
);
8265 ok(ret
== 0, "Release returned %lu\n", ret
);
8267 ret
= IMFTransform_Release(transform
);
8268 ok(ret
== 0, "Release returned %lu\n", ret
);
8274 static void test_color_convert(void)
8276 const GUID transform_inputs
[20] =
8283 DMOVideoFormat_RGB32
,
8284 DMOVideoFormat_RGB565
,
8288 DMOVideoFormat_RGB24
,
8289 DMOVideoFormat_RGB555
,
8290 DMOVideoFormat_RGB8
,
8299 const GUID transform_outputs
[16] =
8306 DMOVideoFormat_RGB32
,
8307 DMOVideoFormat_RGB565
,
8311 DMOVideoFormat_RGB24
,
8312 DMOVideoFormat_RGB555
,
8313 DMOVideoFormat_RGB8
,
8318 const GUID dmo_inputs
[20] =
8326 MEDIASUBTYPE_RGB565
,
8331 MEDIASUBTYPE_RGB555
,
8341 const GUID dmo_outputs
[16] =
8349 MEDIASUBTYPE_RGB565
,
8354 MEDIASUBTYPE_RGB555
,
8361 static const media_type_desc expect_available_inputs
[20] =
8363 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
8364 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
8365 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
8366 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
8367 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
8368 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
8369 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
8370 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
8371 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
8372 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
8373 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
8374 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
8375 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
8376 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
8377 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
8378 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
8379 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
8380 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
8381 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
8382 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
8384 static const media_type_desc expect_available_outputs
[16] =
8386 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
8387 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
8388 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
8389 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
8390 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
8391 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
8392 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
8393 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
8394 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
8395 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
8396 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
8397 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
8398 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
8399 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
8400 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
8401 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
8403 static const media_type_desc expect_available_common
=
8405 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
8406 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
8407 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
8410 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
8411 static const DWORD actual_width
= 96, actual_height
= 96;
8412 const struct attribute_desc input_type_desc
[] =
8414 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
8415 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
8416 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
8417 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
8420 const struct attribute_desc output_type_desc
[] =
8422 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
8423 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
8424 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
8428 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
8429 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
8430 ULONG nv12frame_data_len
, rgb32_data_len
;
8431 const BYTE
*nv12frame_data
, *rgb32_data
;
8432 MFT_OUTPUT_STREAM_INFO output_info
;
8433 MFT_INPUT_STREAM_INFO input_info
;
8434 MFT_OUTPUT_DATA_BUFFER output
;
8435 WCHAR output_path
[MAX_PATH
];
8436 IMFMediaType
*media_type
;
8437 LONGLONG time
, duration
;
8438 IMFTransform
*transform
;
8439 DWORD length
, status
;
8447 hr
= CoInitialize(NULL
);
8448 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
8450 if (!create_transform(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, L
"Color Converter MFT", &MFMediaType_Video
,
8451 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
8452 &transform
, &CLSID_CColorConvertDMO
, &class_id
))
8455 check_dmo(&CLSID_CColorConvertDMO
, L
"Color Converter DMO", &MEDIATYPE_Video
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
8456 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
8458 check_interface(transform
, &IID_IMFTransform
, TRUE
);
8459 check_interface(transform
, &IID_IMediaObject
, TRUE
);
8460 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
8462 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
8463 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
8465 /* check default media types */
8467 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8468 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
8469 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8470 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
8473 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
8475 winetest_push_context("out %lu", i
);
8476 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
8477 check_media_type(media_type
, expect_available_common
, -1);
8478 check_media_type(media_type
, expect_available_outputs
[i
], -1);
8479 ret
= IMFMediaType_Release(media_type
);
8480 ok(ret
== 0, "Release returned %lu\n", ret
);
8481 winetest_pop_context();
8483 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
8484 ok(i
== 16, "%lu output media types\n", i
);
8487 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
8489 winetest_push_context("in %lu", i
);
8490 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
8491 check_media_type(media_type
, expect_available_common
, -1);
8492 check_media_type(media_type
, expect_available_inputs
[i
], -1);
8493 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8497 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
8500 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
8501 ret
= IMFMediaType_Release(media_type
);
8502 ok(ret
== 0, "Release returned %lu\n", ret
);
8503 winetest_pop_context();
8505 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
8506 ok(i
== 20, "%lu input media types\n", i
);
8508 /* check required output media type attributes */
8510 hr
= MFCreateMediaType(&media_type
);
8511 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8512 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8513 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8514 init_media_type(media_type
, output_type_desc
, 1);
8515 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8516 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8517 init_media_type(media_type
, output_type_desc
, 2);
8518 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
8520 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8521 ok(hr
== E_INVALIDARG
, "SetOutputType returned %#lx.\n", hr
);
8522 init_media_type(media_type
, output_type_desc
, i
+ 1);
8524 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8525 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
8526 ret
= IMFMediaType_Release(media_type
);
8527 ok(ret
== 0, "Release returned %lu\n", ret
);
8529 /* check required input media type attributes */
8531 hr
= MFCreateMediaType(&media_type
);
8532 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8533 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8534 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8535 init_media_type(media_type
, input_type_desc
, 1);
8536 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8537 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8538 init_media_type(media_type
, input_type_desc
, 2);
8539 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
8541 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8542 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
8543 init_media_type(media_type
, input_type_desc
, i
+ 1);
8545 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8546 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
8547 ret
= IMFMediaType_Release(media_type
);
8548 ok(ret
== 0, "Release returned %lu\n", ret
);
8550 memset(&input_info
, 0xcd, sizeof(input_info
));
8551 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8552 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
8553 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
8554 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
8555 ok(input_info
.cbSize
== actual_width
* actual_height
* 3 / 2, "got cbSize %#lx\n", input_info
.cbSize
);
8556 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
8557 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
8559 memset(&output_info
, 0xcd, sizeof(output_info
));
8560 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8561 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
8562 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
8563 ok(output_info
.cbSize
== actual_width
* actual_height
* 4, "got cbSize %#lx\n", output_info
.cbSize
);
8564 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
8566 resource
= FindResourceW(NULL
, L
"nv12frame.bin", (const WCHAR
*)RT_RCDATA
);
8567 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8568 nv12frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8569 nv12frame_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8570 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
8572 sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
8573 hr
= IMFSample_SetSampleTime(sample
, 0);
8574 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
8575 hr
= IMFSample_SetSampleDuration(sample
, 10000000);
8576 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
8577 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
8578 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
8579 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
8580 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
8581 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
8582 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
8583 ret
= IMFSample_Release(sample
);
8584 ok(ret
<= 1, "Release returned %ld\n", ret
);
8586 resource
= FindResourceW(NULL
, L
"rgb32frame.bin", (const WCHAR
*)RT_RCDATA
);
8587 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8588 rgb32_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8589 rgb32_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8590 ok(rgb32_data_len
== output_info
.cbSize
, "got length %lu\n", rgb32_data_len
);
8592 /* and generate a new one as well in a temporary directory */
8593 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
8594 lstrcatW(output_path
, L
"rgb32frame.bin");
8595 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
8596 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
8598 status
= 0xdeadbeef;
8599 sample
= create_sample(NULL
, output_info
.cbSize
);
8600 memset(&output
, 0, sizeof(output
));
8601 output
.pSample
= sample
;
8602 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8603 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
8604 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8605 ok(output
.dwStatus
== 0 || broken(output
.dwStatus
== 6) /* win7 */, "got dwStatus %#lx\n", output
.dwStatus
);
8606 ok(status
== 0, "got status %#lx\n", status
);
8608 hr
= IMFSample_GetSampleTime(sample
, &time
);
8609 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
8610 ok(time
== 0, "got time %I64d\n", time
);
8611 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
8612 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
8613 ok(duration
== 10000000, "got duration %I64d\n", duration
);
8614 hr
= IMFSample_GetTotalLength(sample
, &length
);
8615 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8616 ok(length
== output_info
.cbSize
, "got length %lu\n", length
);
8617 check_sample_rgb32(sample
, rgb32_data
, output_file
);
8618 rgb32_data_len
-= output_info
.cbSize
;
8619 rgb32_data
+= output_info
.cbSize
;
8621 trace("created %s\n", debugstr_w(output_path
));
8622 CloseHandle(output_file
);
8624 ret
= IMFSample_Release(sample
);
8625 ok(ret
== 0, "Release returned %lu\n", ret
);
8627 status
= 0xdeadbeef;
8628 sample
= create_sample(NULL
, output_info
.cbSize
);
8629 memset(&output
, 0, sizeof(output
));
8630 output
.pSample
= sample
;
8631 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8632 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
8633 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8634 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
8635 ok(status
== 0, "got status %#lx\n", status
);
8636 hr
= IMFSample_GetTotalLength(sample
, &length
);
8637 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8638 ok(length
== 0, "got length %lu\n", length
);
8639 ret
= IMFSample_Release(sample
);
8640 ok(ret
== 0, "Release returned %lu\n", ret
);
8642 ret
= IMFTransform_Release(transform
);
8643 ok(ret
== 0, "Release returned %ld\n", ret
);
8656 win_skip("Skipping tests on Vista.\n");
8660 test_video_processor();
8662 test_topology_tee_node();
8663 test_topology_loader();
8664 test_topology_loader_evr();
8665 test_MFGetService();
8666 test_sequencer_source();
8667 test_media_session();
8668 test_media_session_rate_control();
8669 test_MFShutdownObject();
8670 test_presentation_clock();
8671 test_sample_grabber();
8672 test_sample_grabber_is_mediatype_supported();
8673 test_quality_manager();
8676 test_MFCreateSimpleTypeHandler();
8677 test_MFGetSupportedMimeTypes();
8678 test_MFGetSupportedSchemes();
8679 test_sample_copier();
8680 test_sample_copier_output_processing();
8681 test_MFGetTopoNodeCurrentType();
8682 test_MFRequireProtectedEnvironment();
8685 test_h264_decoder();
8686 test_audio_convert();
8687 test_color_convert();