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 todo_wine_if(IsEqualGUID(class_ids
, &CLSID_WINEAudioConverter
))
258 ok(i
< count
, "failed to find %s transform\n", debugstr_w(expect_name
));
259 if (i
== count
) return FALSE
;
260 *class_id
= class_ids
[i
];
261 CoTaskMemFree(class_ids
);
262 ok(IsEqualGUID(class_id
, expect_class_id
), "got class id %s\n", debugstr_guid(class_id
));
264 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
268 win_skip("Failed to get %s info, skipping tests.\n", debugstr_w(expect_name
));
272 ok(hr
== S_OK
, "MFTEnum returned %lx\n", hr
);
273 ok(!wcscmp(name
, expect_name
), "got name %s\n", debugstr_w(name
));
274 ok(input_count
== expect_input_count
, "got input_count %u\n", input_count
);
275 for (i
= 0; i
< input_count
; ++i
)
277 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect_major_type
),
278 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
279 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect_input
+ i
),
280 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
282 ok(output_count
== expect_output_count
, "got output_count %u\n", output_count
);
283 for (i
= 0; i
< output_count
; ++i
)
285 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect_major_type
),
286 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
287 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect_output
+ i
),
288 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
290 CoTaskMemFree(output_types
);
291 CoTaskMemFree(input_types
);
295 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)transform
);
299 win_skip("Failed to create %s instance, skipping tests.\n", debugstr_w(expect_name
));
306 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
308 if (IsEqualIID(riid
, &IID_IUnknown
))
311 IUnknown_AddRef(iface
);
316 return E_NOINTERFACE
;
319 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
324 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
329 static const IUnknownVtbl test_unk_vtbl
=
331 test_unk_QueryInterface
,
336 static void test_topology(void)
338 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
339 IMFCollection
*collection
, *collection2
;
340 IUnknown test_unk2
= { &test_unk_vtbl
};
341 IUnknown test_unk
= { &test_unk_vtbl
};
342 IMFTopologyNode
*node
, *node2
, *node3
;
343 IMFTopology
*topology
, *topology2
;
344 DWORD size
, io_count
, index
;
345 MF_TOPOLOGY_TYPE node_type
;
352 hr
= MFCreateTopology(NULL
);
353 ok(hr
== E_POINTER
, "got %#lx\n", hr
);
355 hr
= MFCreateTopology(&topology
);
356 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
357 hr
= IMFTopology_GetTopologyID(topology
, &id
);
358 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
359 ok(id
== 1, "Unexpected id.\n");
361 hr
= MFCreateTopology(&topology2
);
362 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
363 hr
= IMFTopology_GetTopologyID(topology2
, &id
);
364 ok(hr
== S_OK
, "Failed to get id, hr %#lx.\n", hr
);
365 ok(id
== 2, "Unexpected id.\n");
367 IMFTopology_Release(topology
);
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 IMFTopology_Release(topology2
);
377 /* No attributes by default. */
378 for (node_type
= MF_TOPOLOGY_OUTPUT_NODE
; node_type
< MF_TOPOLOGY_TEE_NODE
; ++node_type
)
380 hr
= MFCreateTopologyNode(node_type
, &node
);
381 ok(hr
== S_OK
, "Failed to create a node for type %d, hr %#lx.\n", node_type
, hr
);
382 hr
= IMFTopologyNode_GetCount(node
, &count
);
383 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
384 ok(!count
, "Unexpected attribute count %u.\n", count
);
385 IMFTopologyNode_Release(node
);
388 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, NULL
);
389 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
391 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
392 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
394 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
395 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
397 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
398 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
399 ok(((id
>> 32) == GetCurrentProcessId()) && !!(id
& 0xffff), "Unexpected node id %s.\n", wine_dbgstr_longlong(id
));
401 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
402 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
404 hr
= IMFTopology_GetNodeCount(topology
, NULL
);
405 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
407 hr
= IMFTopology_AddNode(topology
, NULL
);
408 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
411 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
412 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
413 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
415 /* Same id, different nodes. */
416 hr
= IMFTopology_AddNode(topology
, node
);
417 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
420 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
421 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
422 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
424 hr
= IMFTopology_AddNode(topology
, node2
);
425 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
426 IMFTopologyNode_Release(node2
);
428 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
429 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
430 ok(node2
== node
, "Unexpected node.\n");
431 IMFTopologyNode_Release(node2
);
433 /* Change node id, add it again. */
434 hr
= IMFTopologyNode_SetTopoNodeID(node
, ++id
);
435 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
437 hr
= IMFTopology_GetNodeByID(topology
, id
, &node2
);
438 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
439 ok(node2
== node
, "Unexpected node.\n");
440 IMFTopologyNode_Release(node2
);
442 hr
= IMFTopology_GetNodeByID(topology
, id
+ 1, &node2
);
443 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
445 hr
= IMFTopology_AddNode(topology
, node
);
446 ok(hr
== E_INVALIDARG
, "Failed to add a node, hr %#lx.\n", hr
);
448 hr
= IMFTopology_GetNode(topology
, 0, &node2
);
449 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
450 ok(node2
== node
, "Unexpected node.\n");
451 IMFTopologyNode_Release(node2
);
453 hr
= IMFTopology_GetNode(topology
, 1, NULL
);
454 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
456 hr
= IMFTopology_GetNode(topology
, 1, &node2
);
457 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
459 hr
= IMFTopology_GetNode(topology
, -2, &node2
);
460 ok(hr
== MF_E_INVALIDINDEX
, "Failed to get a node, hr %#lx.\n", hr
);
462 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
463 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
464 hr
= IMFTopology_AddNode(topology
, node2
);
465 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
466 IMFTopologyNode_Release(node2
);
469 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
470 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
471 ok(node_count
== 2, "Unexpected node count %u.\n", node_count
);
473 /* Remove with detached node, existing id. */
474 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
475 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
476 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
477 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
478 hr
= IMFTopology_RemoveNode(topology
, node2
);
479 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
480 IMFTopologyNode_Release(node2
);
482 hr
= IMFTopology_RemoveNode(topology
, node
);
483 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
486 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
487 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
488 ok(node_count
== 1, "Unexpected node count %u.\n", node_count
);
490 hr
= IMFTopology_Clear(topology
);
491 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
494 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
495 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
496 ok(node_count
== 0, "Unexpected node count %u.\n", node_count
);
498 hr
= IMFTopology_Clear(topology
);
499 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
501 hr
= IMFTopologyNode_SetTopoNodeID(node
, 123);
502 ok(hr
== S_OK
, "Failed to set node id, hr %#lx.\n", hr
);
504 IMFTopologyNode_Release(node
);
506 /* Change id for attached node. */
507 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
508 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
510 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node2
);
511 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
513 hr
= IMFTopology_AddNode(topology
, node
);
514 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
516 hr
= IMFTopology_AddNode(topology
, node2
);
517 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
519 hr
= IMFTopologyNode_GetTopoNodeID(node
, &id
);
520 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
522 hr
= IMFTopologyNode_SetTopoNodeID(node2
, id
);
523 ok(hr
== S_OK
, "Failed to get node id, hr %#lx.\n", hr
);
525 hr
= IMFTopology_GetNodeByID(topology
, id
, &node3
);
526 ok(hr
== S_OK
, "Failed to get a node, hr %#lx.\n", hr
);
527 ok(node3
== node
, "Unexpected node.\n");
528 IMFTopologyNode_Release(node3
);
530 IMFTopologyNode_Release(node
);
531 IMFTopologyNode_Release(node2
);
533 /* Source/output collections. */
534 hr
= IMFTopology_Clear(topology
);
535 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
537 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
538 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
540 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
541 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
542 ok(!!collection
, "Unexpected object pointer.\n");
544 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection2
);
545 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
546 ok(!!collection2
, "Unexpected object pointer.\n");
547 ok(collection2
!= collection
, "Expected cloned collection.\n");
549 hr
= IMFCollection_GetElementCount(collection
, &size
);
550 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
551 ok(!size
, "Unexpected item count.\n");
553 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)collection
);
554 ok(hr
== S_OK
, "Failed to add element, hr %#lx.\n", hr
);
556 hr
= IMFCollection_GetElementCount(collection
, &size
);
557 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
558 ok(size
== 1, "Unexpected item count.\n");
560 hr
= IMFCollection_GetElementCount(collection2
, &size
);
561 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
562 ok(!size
, "Unexpected item count.\n");
564 IMFCollection_Release(collection2
);
565 IMFCollection_Release(collection
);
567 /* Add some nodes. */
568 hr
= IMFTopology_GetSourceNodeCollection(topology
, NULL
);
569 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
571 hr
= IMFTopology_GetOutputNodeCollection(topology
, NULL
);
572 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
574 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
575 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
576 hr
= IMFTopology_AddNode(topology
, node
);
577 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
578 IMFTopologyNode_Release(node
);
580 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
581 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
582 ok(!!collection
, "Unexpected object pointer.\n");
583 hr
= IMFCollection_GetElementCount(collection
, &size
);
584 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
585 ok(size
== 1, "Unexpected item count.\n");
586 IMFCollection_Release(collection
);
588 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
589 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
590 hr
= IMFTopology_AddNode(topology
, node
);
591 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
592 IMFTopologyNode_Release(node
);
594 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
595 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
596 ok(!!collection
, "Unexpected object pointer.\n");
597 hr
= IMFCollection_GetElementCount(collection
, &size
);
598 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
599 ok(size
== 1, "Unexpected item count.\n");
600 IMFCollection_Release(collection
);
602 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
603 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
604 hr
= IMFTopology_AddNode(topology
, node
);
605 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
606 IMFTopologyNode_Release(node
);
608 hr
= IMFTopology_GetSourceNodeCollection(topology
, &collection
);
609 ok(hr
== S_OK
, "Failed to get source node collection, hr %#lx.\n", hr
);
610 ok(!!collection
, "Unexpected object pointer.\n");
611 hr
= IMFCollection_GetElementCount(collection
, &size
);
612 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
613 ok(size
== 1, "Unexpected item count.\n");
614 IMFCollection_Release(collection
);
616 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node
);
617 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
618 hr
= IMFTopology_AddNode(topology
, node
);
619 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
621 /* Associated object. */
622 hr
= IMFTopologyNode_SetObject(node
, NULL
);
623 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
625 hr
= IMFTopologyNode_GetObject(node
, NULL
);
626 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
628 object
= (void *)0xdeadbeef;
629 hr
= IMFTopologyNode_GetObject(node
, &object
);
630 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
631 ok(!object
, "Unexpected object %p.\n", object
);
633 hr
= IMFTopologyNode_SetObject(node
, &test_unk
);
634 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
636 hr
= IMFTopologyNode_GetObject(node
, &object
);
637 ok(hr
== S_OK
, "Failed to get object, hr %#lx.\n", hr
);
638 ok(object
== &test_unk
, "Unexpected object %p.\n", object
);
639 IUnknown_Release(object
);
641 hr
= IMFTopologyNode_SetObject(node
, &test_unk2
);
642 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
644 hr
= IMFTopologyNode_GetCount(node
, &count
);
645 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
646 ok(count
== 0, "Unexpected attribute count %u.\n", count
);
648 hr
= IMFTopologyNode_SetGUID(node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, &MF_TOPONODE_TRANSFORM_OBJECTID
);
649 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
651 hr
= IMFTopologyNode_SetObject(node
, NULL
);
652 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
654 object
= (void *)0xdeadbeef;
655 hr
= IMFTopologyNode_GetObject(node
, &object
);
656 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
657 ok(!object
, "Unexpected object %p.\n", object
);
659 hr
= IMFTopologyNode_GetCount(node
, &count
);
660 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
661 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
663 /* Preferred stream types. */
664 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
665 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
666 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
668 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype
);
669 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
671 hr
= MFCreateMediaType(&mediatype
);
672 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
674 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
675 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
677 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
678 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
679 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
680 IMFMediaType_Release(mediatype2
);
682 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
683 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
685 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
686 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
687 ok(!mediatype2
, "Unexpected mediatype instance.\n");
689 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
690 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
692 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
693 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
695 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
696 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
697 ok(io_count
== 2, "Unexpected count %lu.\n", io_count
);
699 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
700 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
701 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
703 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, mediatype
);
704 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
706 IMFTopologyNode_Release(node
);
709 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
710 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
712 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, mediatype
);
713 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
715 hr
= IMFTopologyNode_SetOutputPrefType(node
, 2, mediatype
);
716 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
718 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
719 ok(hr
== E_FAIL
, "Failed to get preferred type, hr %#lx.\n", hr
);
720 ok(!mediatype2
, "Unexpected mediatype instance.\n");
722 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
723 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
724 ok(io_count
== 3, "Unexpected count %lu.\n", io_count
);
726 IMFTopologyNode_Release(node
);
729 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_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
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
735 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype2
);
736 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
737 ok(mediatype2
== mediatype
, "Unexpected mediatype instance.\n");
738 IMFMediaType_Release(mediatype2
);
740 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
741 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
743 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
744 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
745 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
747 hr
= IMFTopologyNode_SetInputPrefType(node
, 1, mediatype
);
748 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
750 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
751 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
753 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
754 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
756 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
757 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
759 hr
= MFCreateMediaType(&mediatype2
);
760 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
762 /* Changing output type does not change input type. */
763 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype2
);
764 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
766 hr
= IMFTopologyNode_GetInputPrefType(node
, 0, &mediatype3
);
767 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
768 ok(mediatype3
== mediatype
, "Unexpected mediatype instance.\n");
769 IMFMediaType_Release(mediatype3
);
771 IMFMediaType_Release(mediatype2
);
773 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
774 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
775 ok(io_count
== 0, "Unexpected count %lu.\n", io_count
);
777 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
778 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
779 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
781 IMFTopologyNode_Release(node
);
783 /* Transform node. */
784 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE
, &node
);
785 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
787 hr
= IMFTopologyNode_SetInputPrefType(node
, 3, mediatype
);
788 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
790 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
791 ok(hr
== S_OK
, "Failed to get input count, hr %#lx.\n", hr
);
792 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
794 hr
= IMFTopologyNode_SetOutputPrefType(node
, 4, mediatype
);
795 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
797 hr
= IMFTopologyNode_GetInputCount(node
, &io_count
);
798 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
799 ok(io_count
== 4, "Unexpected count %lu.\n", io_count
);
801 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
802 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
803 ok(io_count
== 5, "Unexpected count %lu.\n", io_count
);
805 IMFTopologyNode_Release(node
);
807 IMFMediaType_Release(mediatype
);
809 hr
= IMFTopology_GetOutputNodeCollection(topology
, &collection
);
810 ok(hr
== S_OK
|| broken(hr
== E_FAIL
) /* before Win8 */, "Failed to get output node collection, hr %#lx.\n", hr
);
813 ok(!!collection
, "Unexpected object pointer.\n");
814 hr
= IMFCollection_GetElementCount(collection
, &size
);
815 ok(hr
== S_OK
, "Failed to get item count, hr %#lx.\n", hr
);
816 ok(size
== 1, "Unexpected item count.\n");
817 IMFCollection_Release(collection
);
820 IMFTopology_Release(topology
);
823 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
824 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
826 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
827 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
830 EXPECT_REF(node2
, 1);
832 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
833 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
836 EXPECT_REF(node2
, 2);
838 IMFTopologyNode_Release(node
);
841 EXPECT_REF(node2
, 2);
843 IMFTopologyNode_Release(node2
);
846 EXPECT_REF(node2
, 1);
848 hr
= IMFTopologyNode_GetNodeType(node2
, &node_type
);
849 ok(hr
== S_OK
, "Failed to get node type, hr %#lx.\n", hr
);
851 IMFTopologyNode_Release(node
);
853 /* Connect within topology. */
854 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
855 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
857 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
858 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
860 hr
= MFCreateTopology(&topology
);
861 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
863 hr
= IMFTopology_AddNode(topology
, node
);
864 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
866 hr
= IMFTopology_AddNode(topology
, node2
);
867 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
870 EXPECT_REF(node2
, 2);
872 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
873 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
876 EXPECT_REF(node2
, 3);
878 hr
= IMFTopology_Clear(topology
);
879 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
882 EXPECT_REF(node2
, 1);
884 /* Removing connected node breaks connection. */
885 hr
= IMFTopology_AddNode(topology
, node
);
886 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
888 hr
= IMFTopology_AddNode(topology
, node2
);
889 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
891 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
892 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
894 hr
= IMFTopology_RemoveNode(topology
, node
);
895 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
898 EXPECT_REF(node2
, 2);
900 hr
= IMFTopologyNode_GetOutput(node
, 0, &node3
, &index
);
901 ok(hr
== MF_E_NOT_FOUND
, "Unexpected hr %#lx.\n", hr
);
903 hr
= IMFTopology_AddNode(topology
, node
);
904 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
906 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 1);
907 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
909 hr
= IMFTopology_RemoveNode(topology
, node2
);
910 ok(hr
== S_OK
, "Failed to remove a node, hr %#lx.\n", hr
);
913 EXPECT_REF(node2
, 1);
915 IMFTopologyNode_Release(node
);
916 IMFTopologyNode_Release(node2
);
918 /* Cloning nodes of different types. */
919 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
920 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
922 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
923 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
925 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
926 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
928 IMFTopologyNode_Release(node2
);
930 /* Cloning preferred types. */
931 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
932 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
934 hr
= MFCreateMediaType(&mediatype
);
935 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
937 hr
= IMFTopologyNode_SetOutputPrefType(node2
, 0, mediatype
);
938 ok(hr
== S_OK
, "Failed to set preferred type, hr %#lx.\n", hr
);
940 /* Vista checks for additional attributes. */
941 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
942 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
944 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
945 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
946 ok(mediatype
== mediatype2
, "Unexpected media type.\n");
948 IMFMediaType_Release(mediatype2
);
949 IMFMediaType_Release(mediatype
);
951 IMFTopologyNode_Release(node2
);
953 /* Existing preferred types are not cleared. */
954 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node2
);
955 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
957 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
958 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
959 ok(io_count
== 1, "Unexpected output count.\n");
961 hr
= IMFTopologyNode_CloneFrom(node
, node2
);
962 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
964 hr
= IMFTopologyNode_GetOutputCount(node
, &io_count
);
965 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
966 ok(io_count
== 1, "Unexpected output count.\n");
968 hr
= IMFTopologyNode_GetOutputPrefType(node
, 0, &mediatype2
);
969 ok(hr
== S_OK
, "Failed to get preferred type, hr %#lx.\n", hr
);
970 ok(!!mediatype2
, "Unexpected media type.\n");
971 IMFMediaType_Release(mediatype2
);
973 hr
= IMFTopologyNode_CloneFrom(node2
, node
);
974 ok(hr
== S_OK
|| broken(hr
== MF_E_ATTRIBUTENOTFOUND
) /* Vista */, "Failed to clone a node, hr %#lx.\n", hr
);
976 hr
= IMFTopologyNode_GetOutputCount(node2
, &io_count
);
977 ok(hr
== S_OK
, "Failed to get output count, hr %#lx.\n", hr
);
978 ok(io_count
== 1, "Unexpected output count.\n");
980 IMFTopologyNode_Release(node2
);
981 IMFTopologyNode_Release(node
);
983 /* Add one node, connect to another that hasn't been added. */
984 hr
= IMFTopology_Clear(topology
);
985 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
987 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &node
);
988 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
990 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &node2
);
991 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
993 hr
= IMFTopology_AddNode(topology
, node
);
994 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
996 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
997 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
998 ok(node_count
== 1, "Unexpected node count.\n");
1000 hr
= IMFTopologyNode_ConnectOutput(node
, 0, node2
, 0);
1001 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1003 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1004 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1005 ok(node_count
== 1, "Unexpected node count.\n");
1007 IMFTopologyNode_Release(node
);
1008 IMFTopologyNode_Release(node2
);
1010 /* Add same node to different topologies. */
1011 hr
= IMFTopology_Clear(topology
);
1012 ok(hr
== S_OK
, "Failed to clear topology, hr %#lx.\n", hr
);
1014 hr
= MFCreateTopology(&topology2
);
1015 ok(hr
== S_OK
, "Failed to create 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
= IMFTopology_AddNode(topology
, node
);
1021 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1022 EXPECT_REF(node
, 2);
1024 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1025 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1026 ok(node_count
== 1, "Unexpected node count.\n");
1028 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
1029 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1030 ok(node_count
== 0, "Unexpected node count.\n");
1032 hr
= IMFTopology_AddNode(topology2
, node
);
1033 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
1034 EXPECT_REF(node
, 3);
1036 hr
= IMFTopology_GetNodeCount(topology
, &node_count
);
1037 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1038 ok(node_count
== 1, "Unexpected node count.\n");
1040 hr
= IMFTopology_GetNodeCount(topology2
, &node_count
);
1041 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
1042 ok(node_count
== 1, "Unexpected node count.\n");
1044 IMFTopology_Release(topology2
);
1045 IMFTopology_Release(topology
);
1048 static void test_topology_tee_node(void)
1050 IMFTopologyNode
*src_node
, *tee_node
;
1051 IMFMediaType
*mediatype
, *mediatype2
;
1052 IMFTopology
*topology
;
1056 hr
= MFCreateTopology(&topology
);
1057 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
1059 hr
= MFCreateMediaType(&mediatype
);
1060 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1062 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &tee_node
);
1063 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1065 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
1066 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
1068 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 0, mediatype
);
1069 ok(hr
== S_OK
, "Failed to set type, hr %#lx.\n", hr
);
1071 /* Even though tee node has only one input and source has only one output,
1072 it's possible to connect to higher inputs/outputs. */
1074 /* SRC(0) -> TEE(0) */
1075 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 0);
1076 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1078 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
1079 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1080 ok(count
== 1, "Unexpected count %lu.\n", count
);
1082 hr
= IMFTopologyNode_GetInputPrefType(tee_node
, 0, &mediatype2
);
1083 ok(hr
== S_OK
, "Failed to get type, hr %#lx.\n", hr
);
1084 ok(mediatype2
== mediatype
, "Unexpected type.\n");
1085 IMFMediaType_Release(mediatype2
);
1087 /* SRC(0) -> TEE(1) */
1088 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, tee_node
, 1);
1089 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1091 hr
= IMFTopologyNode_GetInputCount(tee_node
, &count
);
1092 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1093 ok(count
== 2, "Unexpected count %lu.\n", count
);
1095 hr
= IMFTopologyNode_SetInputPrefType(tee_node
, 1, mediatype
);
1096 ok(hr
== MF_E_INVALIDTYPE
, "Unexpected hr %#lx.\n", hr
);
1098 /* SRC(1) -> TEE(1) */
1099 hr
= IMFTopologyNode_ConnectOutput(src_node
, 1, tee_node
, 1);
1100 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
1102 hr
= IMFTopologyNode_GetOutputCount(src_node
, &count
);
1103 ok(hr
== S_OK
, "Failed to get count, hr %#lx.\n", hr
);
1104 ok(count
== 2, "Unexpected count %lu.\n", count
);
1106 IMFMediaType_Release(mediatype
);
1107 IMFTopologyNode_Release(src_node
);
1108 IMFTopologyNode_Release(tee_node
);
1109 IMFTopology_Release(topology
);
1112 static HRESULT WINAPI
test_getservice_QI(IMFGetService
*iface
, REFIID riid
, void **obj
)
1114 if (IsEqualIID(riid
, &IID_IMFGetService
) || IsEqualIID(riid
, &IID_IUnknown
))
1121 return E_NOINTERFACE
;
1124 static ULONG WINAPI
test_getservice_AddRef(IMFGetService
*iface
)
1129 static ULONG WINAPI
test_getservice_Release(IMFGetService
*iface
)
1134 static HRESULT WINAPI
test_getservice_GetService(IMFGetService
*iface
, REFGUID service
, REFIID riid
, void **obj
)
1136 *obj
= (void *)0xdeadbeef;
1140 static const IMFGetServiceVtbl testmfgetservicevtbl
=
1143 test_getservice_AddRef
,
1144 test_getservice_Release
,
1145 test_getservice_GetService
,
1148 static IMFGetService test_getservice
= { &testmfgetservicevtbl
};
1150 static HRESULT WINAPI
testservice_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1152 if (IsEqualIID(riid
, &IID_IUnknown
))
1160 if (IsEqualIID(riid
, &IID_IMFGetService
))
1163 return E_NOINTERFACE
;
1166 static HRESULT WINAPI
testservice2_QI(IUnknown
*iface
, REFIID riid
, void **obj
)
1168 if (IsEqualIID(riid
, &IID_IUnknown
))
1174 if (IsEqualIID(riid
, &IID_IMFGetService
))
1176 *obj
= &test_getservice
;
1181 return E_NOINTERFACE
;
1184 static ULONG WINAPI
testservice_AddRef(IUnknown
*iface
)
1189 static ULONG WINAPI
testservice_Release(IUnknown
*iface
)
1194 static const IUnknownVtbl testservicevtbl
=
1198 testservice_Release
,
1201 static const IUnknownVtbl testservice2vtbl
=
1205 testservice_Release
,
1208 static IUnknown testservice
= { &testservicevtbl
};
1209 static IUnknown testservice2
= { &testservice2vtbl
};
1211 static void test_MFGetService(void)
1216 hr
= MFGetService(NULL
, NULL
, NULL
, NULL
);
1217 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1219 unk
= (void *)0xdeadbeef;
1220 hr
= MFGetService(NULL
, NULL
, NULL
, (void **)&unk
);
1221 ok(hr
== E_POINTER
, "Unexpected return value %#lx.\n", hr
);
1222 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1224 hr
= MFGetService(&testservice
, NULL
, NULL
, NULL
);
1225 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1227 unk
= (void *)0xdeadbeef;
1228 hr
= MFGetService(&testservice
, NULL
, NULL
, (void **)&unk
);
1229 ok(hr
== 0x82eddead, "Unexpected return value %#lx.\n", hr
);
1230 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1233 hr
= MFGetService(&testservice2
, NULL
, NULL
, (void **)&unk
);
1234 ok(hr
== 0x83eddead, "Unexpected return value %#lx.\n", hr
);
1235 ok(unk
== (void *)0xdeadbeef, "Unexpected out object.\n");
1238 static void test_sequencer_source(void)
1240 IMFSequencerSource
*seq_source
;
1243 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1244 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1246 hr
= MFCreateSequencerSource(NULL
, &seq_source
);
1247 ok(hr
== S_OK
, "Failed to create sequencer source, hr %#lx.\n", hr
);
1249 check_interface(seq_source
, &IID_IMFMediaSourceTopologyProvider
, TRUE
);
1251 IMFSequencerSource_Release(seq_source
);
1254 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1257 struct test_callback
1259 IMFAsyncCallback IMFAsyncCallback_iface
;
1262 static HRESULT WINAPI
testcallback_QueryInterface(IMFAsyncCallback
*iface
, REFIID riid
, void **obj
)
1264 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
1265 IsEqualIID(riid
, &IID_IUnknown
))
1268 IMFAsyncCallback_AddRef(iface
);
1273 return E_NOINTERFACE
;
1276 static ULONG WINAPI
testcallback_AddRef(IMFAsyncCallback
*iface
)
1281 static ULONG WINAPI
testcallback_Release(IMFAsyncCallback
*iface
)
1286 static HRESULT WINAPI
testcallback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
, DWORD
*queue
)
1288 ok(flags
!= NULL
&& queue
!= NULL
, "Unexpected arguments.\n");
1292 static HRESULT WINAPI
testcallback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1294 ok(result
!= NULL
, "Unexpected result object.\n");
1299 static const IMFAsyncCallbackVtbl testcallbackvtbl
=
1301 testcallback_QueryInterface
,
1302 testcallback_AddRef
,
1303 testcallback_Release
,
1304 testcallback_GetParameters
,
1305 testcallback_Invoke
,
1308 static void init_test_callback(struct test_callback
*callback
)
1310 callback
->IMFAsyncCallback_iface
.lpVtbl
= &testcallbackvtbl
;
1313 static void test_session_events(IMFMediaSession
*session
)
1315 struct test_callback callback
, callback2
;
1316 IMFAsyncResult
*result
;
1317 IMFMediaEvent
*event
;
1320 init_test_callback(&callback
);
1321 init_test_callback(&callback2
);
1323 hr
= IMFMediaSession_GetEvent(session
, MF_EVENT_FLAG_NO_WAIT
, &event
);
1324 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
1327 hr
= IMFMediaSession_BeginGetEvent(session
, NULL
, NULL
);
1328 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
1330 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1331 ok(hr
== S_OK
, "Failed to Begin*, hr %#lx.\n", hr
);
1333 /* Same callback, same state. */
1334 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1335 ok(hr
== MF_S_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1337 /* Same callback, different state. */
1338 hr
= IMFMediaSession_BeginGetEvent(session
, &callback
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1339 ok(hr
== MF_E_MULTIPLE_BEGIN
, "Unexpected hr %#lx.\n", hr
);
1341 /* Different callback, same state. */
1342 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)session
);
1343 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1345 /* Different callback, different state. */
1346 hr
= IMFMediaSession_BeginGetEvent(session
, &callback2
.IMFAsyncCallback_iface
, (IUnknown
*)&callback
.IMFAsyncCallback_iface
);
1347 ok(hr
== MF_E_MULTIPLE_SUBSCRIBERS
, "Unexpected hr %#lx.\n", hr
);
1349 hr
= MFCreateAsyncResult(NULL
, &callback
.IMFAsyncCallback_iface
, NULL
, &result
);
1350 ok(hr
== S_OK
, "Failed to create result, hr %#lx.\n", hr
);
1352 hr
= IMFMediaSession_EndGetEvent(session
, result
, &event
);
1353 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
1355 /* Shutdown behavior. */
1356 hr
= IMFMediaSession_Shutdown(session
);
1357 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1360 static void test_media_session(void)
1362 IMFRateSupport
*rate_support
;
1363 IMFAttributes
*attributes
;
1364 IMFMediaSession
*session
;
1365 MFSHUTDOWN_STATUS status
;
1366 IMFTopology
*topology
;
1367 IMFShutdown
*shutdown
;
1368 PROPVARIANT propvar
;
1374 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1375 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1377 hr
= MFCreateMediaSession(NULL
, &session
);
1378 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1380 check_interface(session
, &IID_IMFGetService
, TRUE
);
1381 check_interface(session
, &IID_IMFRateSupport
, TRUE
);
1382 check_interface(session
, &IID_IMFRateControl
, TRUE
);
1383 check_interface(session
, &IID_IMFAttributes
, FALSE
);
1384 check_interface(session
, &IID_IMFTopologyNodeAttributeEditor
, FALSE
);
1385 check_interface(session
, &IID_IMFLocalMFTRegistration
, FALSE
);
1386 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
1387 check_service_interface(session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, TRUE
);
1388 check_service_interface(session
, &MF_TOPONODE_ATTRIBUTE_EDITOR_SERVICE
, &IID_IMFTopologyNodeAttributeEditor
, TRUE
);
1389 check_service_interface(session
, &MF_LOCAL_MFT_REGISTRATION_SERVICE
, &IID_IMFLocalMFTRegistration
, TRUE
);
1391 hr
= IMFMediaSession_GetClock(session
, &clock
);
1392 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1394 hr
= IMFClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
1395 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1397 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1398 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
1400 hr
= IMFMediaSession_Shutdown(session
);
1401 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
1403 check_interface(session
, &IID_IMFGetService
, TRUE
);
1405 hr
= IMFMediaSession_QueryInterface(session
, &IID_IMFGetService
, (void **)&gs
);
1406 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1408 hr
= IMFGetService_GetService(gs
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1409 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1411 IMFGetService_Release(gs
);
1413 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
1414 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1415 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected shutdown status %u.\n", status
);
1417 IMFShutdown_Release(shutdown
);
1419 hr
= IMFMediaSession_ClearTopologies(session
);
1420 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1422 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, NULL
);
1423 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1425 propvar
.vt
= VT_EMPTY
;
1426 hr
= IMFMediaSession_Start(session
, &GUID_NULL
, &propvar
);
1427 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1429 hr
= IMFMediaSession_Pause(session
);
1430 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1432 hr
= IMFMediaSession_Stop(session
);
1433 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1435 hr
= IMFMediaSession_Close(session
);
1436 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1438 hr
= IMFMediaSession_GetClock(session
, &clock
);
1439 ok(hr
== MF_E_SHUTDOWN
|| broken(hr
== E_UNEXPECTED
) /* Win7 */, "Unexpected hr %#lx.\n", hr
);
1441 hr
= IMFMediaSession_GetSessionCapabilities(session
, &caps
);
1442 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1444 hr
= IMFMediaSession_GetSessionCapabilities(session
, NULL
);
1445 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
1447 hr
= IMFMediaSession_GetFullTopology(session
, MFSESSION_GETFULLTOPOLOGY_CURRENT
, 0, &topology
);
1448 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1450 hr
= IMFMediaSession_Shutdown(session
);
1451 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
1453 IMFMediaSession_Release(session
);
1455 /* Custom topology loader, GUID is not registered. */
1456 hr
= MFCreateAttributes(&attributes
, 1);
1457 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
1459 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_TOPOLOADER
, &MF_SESSION_TOPOLOADER
);
1460 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1462 hr
= MFCreateMediaSession(attributes
, &session
);
1463 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1464 IMFMediaSession_Release(session
);
1466 /* Disabled quality manager. */
1467 hr
= IMFAttributes_SetGUID(attributes
, &MF_SESSION_QUALITY_MANAGER
, &GUID_NULL
);
1468 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1470 hr
= MFCreateMediaSession(attributes
, &session
);
1471 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1472 IMFMediaSession_Release(session
);
1474 IMFAttributes_Release(attributes
);
1476 /* Basic events behavior. */
1477 hr
= MFCreateMediaSession(NULL
, &session
);
1478 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1480 test_session_events(session
);
1482 IMFMediaSession_Release(session
);
1485 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1488 static void test_media_session_rate_control(void)
1490 IMFRateControl
*rate_control
, *clock_rate_control
;
1491 IMFPresentationClock
*presentation_clock
;
1492 IMFPresentationTimeSource
*time_source
;
1493 MFCLOCK_PROPERTIES clock_props
;
1494 IMFRateSupport
*rate_support
;
1495 IMFMediaSession
*session
;
1501 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
1502 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
1504 hr
= MFCreateMediaSession(NULL
, &session
);
1505 ok(hr
== S_OK
, "Failed to create media session, hr %#lx.\n", hr
);
1507 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
);
1508 ok(hr
== S_OK
, "Failed to get rate support interface, hr %#lx.\n", hr
);
1510 hr
= MFGetService((IUnknown
*)session
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, (void **)&rate_control
);
1511 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
1513 hr
= IMFRateControl_GetRate(rate_control
, NULL
, NULL
);
1514 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1517 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
1518 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1519 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1521 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
1522 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
1526 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
1527 ok(hr
== S_OK
, "Failed to get playback rate, hr %#lx.\n", hr
);
1528 ok(!thin
, "Unexpected thinning.\n");
1529 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1531 hr
= IMFMediaSession_GetClock(session
, &clock
);
1532 ok(hr
== S_OK
, "Failed to get clock, hr %#lx.\n", hr
);
1534 hr
= IMFClock_QueryInterface(clock
, &IID_IMFPresentationClock
, (void **)&presentation_clock
);
1535 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1537 hr
= IMFClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&clock_rate_control
);
1538 ok(hr
== S_OK
, "Failed to get rate control, hr %#lx.\n", hr
);
1541 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1542 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1543 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1545 hr
= IMFRateControl_SetRate(clock_rate_control
, FALSE
, 1.5f
);
1546 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1548 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1549 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1551 hr
= IMFClock_GetProperties(clock
, &clock_props
);
1552 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
1554 hr
= MFCreateSystemTimeSource(&time_source
);
1555 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
1557 hr
= IMFPresentationClock_SetTimeSource(presentation_clock
, time_source
);
1558 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
1560 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.5f
);
1561 ok(hr
== S_OK
, "Failed to set rate, hr %#lx.\n", hr
);
1564 hr
= IMFRateControl_GetRate(clock_rate_control
, NULL
, &rate
);
1565 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
1566 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
1568 IMFPresentationTimeSource_Release(time_source
);
1570 IMFRateControl_Release(clock_rate_control
);
1571 IMFPresentationClock_Release(presentation_clock
);
1572 IMFClock_Release(clock
);
1574 IMFRateControl_Release(rate_control
);
1575 IMFRateSupport_Release(rate_support
);
1577 IMFMediaSession_Release(session
);
1580 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
1583 static HRESULT WINAPI
test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
,
1586 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
1587 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
1588 IsEqualIID(riid
, &IID_IUnknown
))
1591 IMFSampleGrabberSinkCallback_AddRef(iface
);
1596 return E_NOINTERFACE
;
1599 static ULONG WINAPI
test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
1604 static ULONG WINAPI
test_grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
1609 static HRESULT WINAPI
test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
,
1615 static HRESULT WINAPI
test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1620 static HRESULT WINAPI
test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1625 static HRESULT WINAPI
test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
)
1630 static HRESULT WINAPI
test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME systime
, float rate
)
1635 static HRESULT WINAPI
test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
1636 IMFPresentationClock
*clock
)
1641 static HRESULT WINAPI
test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
1642 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
1647 static HRESULT WINAPI
test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
1652 static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl
=
1654 test_grabber_callback_QueryInterface
,
1655 test_grabber_callback_AddRef
,
1656 test_grabber_callback_Release
,
1657 test_grabber_callback_OnClockStart
,
1658 test_grabber_callback_OnClockStop
,
1659 test_grabber_callback_OnClockPause
,
1660 test_grabber_callback_OnClockRestart
,
1661 test_grabber_callback_OnClockSetRate
,
1662 test_grabber_callback_OnSetPresentationClock
,
1663 test_grabber_callback_OnProcessSample
,
1664 test_grabber_callback_OnShutdown
,
1669 IMFMediaSource IMFMediaSource_iface
;
1673 static struct test_source
*impl_from_IMFMediaSource(IMFMediaSource
*iface
)
1675 return CONTAINING_RECORD(iface
, struct test_source
, IMFMediaSource_iface
);
1678 static HRESULT WINAPI
test_source_QueryInterface(IMFMediaSource
*iface
, REFIID riid
, void **out
)
1680 if (IsEqualIID(riid
, &IID_IMFMediaSource
)
1681 || IsEqualIID(riid
, &IID_IMFMediaEventGenerator
)
1682 || IsEqualIID(riid
, &IID_IUnknown
))
1689 return E_NOINTERFACE
;
1692 IMFMediaSource_AddRef(iface
);
1696 static ULONG WINAPI
test_source_AddRef(IMFMediaSource
*iface
)
1698 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1699 return InterlockedIncrement(&source
->refcount
);
1702 static ULONG WINAPI
test_source_Release(IMFMediaSource
*iface
)
1704 struct test_source
*source
= impl_from_IMFMediaSource(iface
);
1705 ULONG refcount
= InterlockedDecrement(&source
->refcount
);
1713 static HRESULT WINAPI
test_source_GetEvent(IMFMediaSource
*iface
, DWORD flags
, IMFMediaEvent
**event
)
1715 ok(0, "Unexpected call.\n");
1719 static HRESULT WINAPI
test_source_BeginGetEvent(IMFMediaSource
*iface
, IMFAsyncCallback
*callback
, IUnknown
*state
)
1721 ok(0, "Unexpected call.\n");
1725 static HRESULT WINAPI
test_source_EndGetEvent(IMFMediaSource
*iface
, IMFAsyncResult
*result
, IMFMediaEvent
**event
)
1727 ok(0, "Unexpected call.\n");
1731 static HRESULT WINAPI
test_source_QueueEvent(IMFMediaSource
*iface
, MediaEventType event_type
, REFGUID ext_type
,
1732 HRESULT hr
, const PROPVARIANT
*value
)
1734 ok(0, "Unexpected call.\n");
1738 static HRESULT WINAPI
test_source_GetCharacteristics(IMFMediaSource
*iface
, DWORD
*flags
)
1740 ok(0, "Unexpected call.\n");
1744 static HRESULT WINAPI
test_source_CreatePresentationDescriptor(IMFMediaSource
*iface
, IMFPresentationDescriptor
**pd
)
1746 ok(0, "Unexpected call.\n");
1750 static HRESULT WINAPI
test_source_Start(IMFMediaSource
*iface
, IMFPresentationDescriptor
*pd
, const GUID
*time_format
,
1751 const PROPVARIANT
*start_position
)
1753 ok(0, "Unexpected call.\n");
1757 static HRESULT WINAPI
test_source_Stop(IMFMediaSource
*iface
)
1759 ok(0, "Unexpected call.\n");
1763 static HRESULT WINAPI
test_source_Pause(IMFMediaSource
*iface
)
1765 ok(0, "Unexpected call.\n");
1769 static HRESULT WINAPI
test_source_Shutdown(IMFMediaSource
*iface
)
1771 ok(0, "Unexpected call.\n");
1775 static const IMFMediaSourceVtbl test_source_vtbl
=
1777 test_source_QueryInterface
,
1779 test_source_Release
,
1780 test_source_GetEvent
,
1781 test_source_BeginGetEvent
,
1782 test_source_EndGetEvent
,
1783 test_source_QueueEvent
,
1784 test_source_GetCharacteristics
,
1785 test_source_CreatePresentationDescriptor
,
1789 test_source_Shutdown
,
1792 static IMFMediaSource
*create_test_source(void)
1794 struct test_source
*source
;
1796 source
= calloc(1, sizeof(*source
));
1797 source
->IMFMediaSource_iface
.lpVtbl
= &test_source_vtbl
;
1798 source
->refcount
= 1;
1800 return &source
->IMFMediaSource_iface
;
1803 static void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
1808 hr
= IMFMediaType_DeleteAllItems(mediatype
);
1809 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1811 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
1813 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
1814 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
1818 static void init_source_node(IMFMediaType
*mediatype
, IMFMediaSource
*source
, IMFTopologyNode
*node
)
1820 IMFPresentationDescriptor
*pd
;
1821 IMFMediaTypeHandler
*handler
;
1822 IMFStreamDescriptor
*sd
;
1825 hr
= IMFTopologyNode_DeleteAllItems(node
);
1826 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1828 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
1829 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
1831 hr
= IMFStreamDescriptor_GetMediaTypeHandler(sd
, &handler
);
1832 ok(hr
== S_OK
, "Failed to get media type handler, hr %#lx.\n", hr
);
1834 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
1835 ok(hr
== S_OK
, "Failed to set current media type, hr %#lx.\n", hr
);
1837 IMFMediaTypeHandler_Release(handler
);
1839 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
1840 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
1842 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
1843 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
1845 IMFPresentationDescriptor_Release(pd
);
1847 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
1848 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
1852 hr
= IMFTopologyNode_SetUnknown(node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
1853 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1856 IMFStreamDescriptor_Release(sd
);
1859 static void init_sink_node(IMFActivate
*sink_activate
, unsigned int method
, IMFTopologyNode
*node
)
1861 IMFStreamSink
*stream_sink
;
1865 hr
= IMFTopologyNode_DeleteAllItems(node
);
1866 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1868 hr
= IMFActivate_ActivateObject(sink_activate
, &IID_IMFMediaSink
, (void **)&sink
);
1869 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
1871 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
1872 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1874 IMFMediaSink_Release(sink
);
1876 hr
= IMFTopologyNode_SetObject(node
, (IUnknown
*)stream_sink
);
1877 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
1879 IMFStreamSink_Release(stream_sink
);
1881 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_CONNECT_METHOD
, method
);
1882 ok(hr
== S_OK
, "Failed to set connect method, hr %#lx.\n", hr
);
1885 enum loader_test_flags
1887 LOADER_EXPECTED_DECODER
= 0x1,
1888 LOADER_EXPECTED_CONVERTER
= 0x2,
1890 LOADER_NEEDS_VIDEO_PROCESSOR
= 0x8,
1893 static void test_topology_loader(void)
1895 static const struct loader_test
1897 media_type_desc input_type
;
1898 media_type_desc output_type
;
1899 MF_CONNECT_METHOD method
;
1900 HRESULT expected_result
;
1906 /* PCM -> PCM, same type */
1908 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1909 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1910 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1911 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1912 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1913 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1914 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1917 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1918 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1919 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1920 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1921 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1922 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1923 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1931 /* PCM -> PCM, different bps. */
1933 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1934 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1935 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1936 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1937 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1938 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1939 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1942 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1943 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1944 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1945 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1946 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000),
1947 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1948 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1952 MF_E_INVALIDMEDIATYPE
,
1956 /* PCM -> PCM, different bps. */
1958 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1959 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1960 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1961 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1962 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1963 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1964 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1967 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1968 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1969 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1970 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1971 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 48000),
1972 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1973 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
1976 MF_CONNECT_ALLOW_CONVERTER
,
1978 LOADER_NEEDS_VIDEO_PROCESSOR
| LOADER_EXPECTED_CONVERTER
| LOADER_TODO
,
1984 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1985 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
1986 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
1987 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1988 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
1989 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1992 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1993 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1994 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1995 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1996 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
1997 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1998 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2002 MF_E_INVALIDMEDIATYPE
,
2008 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2009 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
2010 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2011 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2012 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
2013 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2016 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2017 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2018 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2019 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2020 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
2021 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2022 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2025 MF_CONNECT_ALLOW_CONVERTER
,
2026 MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION
,
2027 LOADER_NEEDS_VIDEO_PROCESSOR
| LOADER_TODO
,
2033 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2034 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
2035 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2036 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2037 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 16000),
2038 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2041 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2042 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2043 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2044 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2045 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
2046 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2047 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
2050 MF_CONNECT_ALLOW_DECODER
,
2052 LOADER_EXPECTED_DECODER
| LOADER_TODO
,
2056 IMFSampleGrabberSinkCallback test_grabber_callback
= { &test_grabber_callback_vtbl
};
2057 IMFTopologyNode
*src_node
, *sink_node
, *src_node2
, *sink_node2
, *mft_node
;
2058 IMFTopology
*topology
, *topology2
, *full_topology
;
2059 IMFMediaType
*media_type
, *input_type
, *output_type
;
2060 IMFPresentationDescriptor
*pd
;
2061 unsigned int i
, count
, value
;
2062 IMFActivate
*sink_activate
;
2063 MF_TOPOLOGY_TYPE node_type
;
2064 IMFStreamDescriptor
*sd
;
2065 IMFTransform
*transform
;
2066 IMFMediaSource
*source
;
2067 IMFTopoLoader
*loader
;
2068 IUnknown
*node_object
;
2075 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2076 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
2078 hr
= MFCreateTopoLoader(NULL
);
2079 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2081 hr
= MFCreateTopoLoader(&loader
);
2082 ok(hr
== S_OK
, "Failed to create topology loader, hr %#lx.\n", hr
);
2084 hr
= MFCreateTopology(&topology
);
2085 ok(hr
== S_OK
, "Failed to create topology, hr %#lx.\n", hr
);
2087 /* Empty topology */
2088 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2090 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2092 /* Add source node. */
2093 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &src_node
);
2094 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2096 /* When a decoder is involved, windows requires this attribute to be present */
2097 source
= create_test_source();
2099 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_SOURCE
, (IUnknown
*)source
);
2100 ok(hr
== S_OK
, "Failed to set node source, hr %#lx.\n", hr
);
2102 hr
= MFCreateMediaType(&media_type
);
2103 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2105 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2106 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2107 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2108 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2110 hr
= MFCreateStreamDescriptor(0, 1, &media_type
, &sd
);
2111 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
2113 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_STREAM_DESCRIPTOR
, (IUnknown
*)sd
);
2114 ok(hr
== S_OK
, "Failed to set node sd, hr %#lx.\n", hr
);
2116 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
2117 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
2119 hr
= IMFTopologyNode_SetUnknown(src_node
, &MF_TOPONODE_PRESENTATION_DESCRIPTOR
, (IUnknown
*)pd
);
2120 ok(hr
== S_OK
, "Failed to set node pd, hr %#lx.\n", hr
);
2122 IMFPresentationDescriptor_Release(pd
);
2123 IMFStreamDescriptor_Release(sd
);
2124 IMFMediaType_Release(media_type
);
2126 hr
= IMFTopology_AddNode(topology
, src_node
);
2127 ok(hr
== S_OK
, "Failed to add a node, hr %#lx.\n", hr
);
2129 /* Source node only. */
2130 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2132 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2134 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &sink_node
);
2135 ok(hr
== S_OK
, "Failed to create output node, hr %#lx.\n", hr
);
2137 hr
= MFCreateMediaType(&media_type
);
2138 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2140 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
2141 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2142 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
2143 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2145 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &test_grabber_callback
, &sink_activate
);
2146 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2148 hr
= IMFTopologyNode_SetObject(sink_node
, (IUnknown
*)sink_activate
);
2149 ok(hr
== S_OK
, "Failed to set object, hr %#lx.\n", hr
);
2151 IMFMediaType_Release(media_type
);
2153 hr
= IMFTopology_AddNode(topology
, sink_node
);
2154 ok(hr
== S_OK
, "Failed to add sink node, hr %#lx.\n", hr
);
2156 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2158 ok(hr
== MF_E_TOPO_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2160 hr
= IMFTopologyNode_ConnectOutput(src_node
, 0, sink_node
, 0);
2161 ok(hr
== S_OK
, "Failed to connect nodes, hr %#lx.\n", hr
);
2163 /* Sink was not resolved. */
2164 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2165 ok(hr
== MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2167 hr
= MFCreateMediaType(&input_type
);
2168 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2170 hr
= MFCreateMediaType(&output_type
);
2171 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2173 for (i
= 0; i
< ARRAY_SIZE(loader_tests
); ++i
)
2175 const struct loader_test
*test
= &loader_tests
[i
];
2177 init_media_type(input_type
, test
->input_type
, -1);
2178 init_media_type(output_type
, test
->output_type
, -1);
2180 hr
= MFCreateSampleGrabberSinkActivate(output_type
, &test_grabber_callback
, &sink_activate
);
2181 ok(hr
== S_OK
, "Failed to create grabber sink, hr %#lx.\n", hr
);
2183 init_source_node(input_type
, source
, src_node
);
2184 init_sink_node(sink_activate
, test
->method
, sink_node
);
2186 hr
= IMFTopology_GetCount(topology
, &count
);
2187 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2188 ok(!count
, "Unexpected count %u.\n", count
);
2190 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2191 if (test
->flags
& LOADER_NEEDS_VIDEO_PROCESSOR
&& !has_video_processor
)
2192 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx on test %u.\n", hr
, i
);
2195 todo_wine_if(test
->flags
& LOADER_TODO
)
2196 ok(hr
== test
->expected_result
, "Unexpected hr %#lx on test %u.\n", hr
, i
);
2197 ok(full_topology
!= topology
, "Unexpected instance.\n");
2200 if (test
->expected_result
== S_OK
&& hr
== S_OK
)
2202 hr
= IMFTopology_GetCount(full_topology
, &count
);
2203 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2205 ok(count
== 1, "Unexpected count %u.\n", count
);
2208 hr
= IMFTopology_GetUINT32(full_topology
, &MF_TOPOLOGY_RESOLUTION_STATUS
, &value
);
2210 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2211 ok(value
== MF_TOPOLOGY_RESOLUTION_SUCCEEDED
, "Unexpected value %#x.\n", value
);
2214 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2216 if (test
->flags
& LOADER_EXPECTED_CONVERTER
)
2219 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2220 ok(hr
== S_OK
, "Failed to get node count, hr %#lx.\n", hr
);
2221 todo_wine_if(test
->flags
& (LOADER_EXPECTED_CONVERTER
| LOADER_EXPECTED_DECODER
))
2222 ok(node_count
== count
, "Unexpected node count %u.\n", node_count
);
2224 hr
= IMFTopologyNode_GetTopoNodeID(src_node
, &node_id
);
2225 ok(hr
== S_OK
, "Failed to get source node id, hr %#lx.\n", hr
);
2227 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &src_node2
);
2228 ok(hr
== S_OK
, "Failed to get source in resolved topology, hr %#lx.\n", hr
);
2230 hr
= IMFTopologyNode_GetTopoNodeID(sink_node
, &node_id
);
2231 ok(hr
== S_OK
, "Failed to get sink node id, hr %#lx.\n", hr
);
2233 hr
= IMFTopology_GetNodeByID(full_topology
, node_id
, &sink_node2
);
2234 ok(hr
== S_OK
, "Failed to get sink in resolved topology, hr %#lx.\n", hr
);
2236 if (test
->flags
& (LOADER_EXPECTED_DECODER
| LOADER_EXPECTED_CONVERTER
) && strcmp(winetest_platform
, "wine"))
2238 hr
= IMFTopologyNode_GetOutput(src_node2
, 0, &mft_node
, &index
);
2239 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2240 ok(!index
, "Unexpected stream index %lu.\n", index
);
2242 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2243 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2244 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2246 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2247 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2249 if (test
->flags
& LOADER_EXPECTED_DECODER
)
2252 hr
= IMFTopologyNode_GetUINT32(mft_node
, &MF_TOPONODE_DECODER
, &value
);
2253 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2254 ok(value
== 1, "Unexpected value.\n");
2257 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2258 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2260 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void **)&transform
);
2261 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2262 IUnknown_Release(node_object
);
2264 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
2265 ok(hr
== S_OK
, "Failed to get transform input type, hr %#lx.\n", hr
);
2267 hr
= IMFMediaType_Compare(input_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2268 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2269 ok(ret
, "Input type of first transform doesn't match source node type.\n");
2271 IMFTopologyNode_Release(mft_node
);
2272 IMFMediaType_Release(media_type
);
2273 IMFTransform_Release(transform
);
2275 hr
= IMFTopologyNode_GetInput(sink_node2
, 0, &mft_node
, &index
);
2276 ok(hr
== S_OK
, "Failed to get transform node in resolved topology, hr %#lx.\n", hr
);
2277 ok(!index
, "Unexpected stream index %lu.\n", index
);
2279 hr
= IMFTopologyNode_GetNodeType(mft_node
, &node_type
);
2280 ok(hr
== S_OK
, "Failed to get transform node type in resolved topology, hr %#lx.\n", hr
);
2281 ok(node_type
== MF_TOPOLOGY_TRANSFORM_NODE
, "Unexpected node type %u.\n", node_type
);
2283 hr
= IMFTopologyNode_GetItem(mft_node
, &MF_TOPONODE_TRANSFORM_OBJECTID
, NULL
);
2284 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
2286 hr
= IMFTopologyNode_GetObject(mft_node
, &node_object
);
2287 ok(hr
== S_OK
, "Failed to get object of transform node, hr %#lx.\n", hr
);
2289 hr
= IUnknown_QueryInterface(node_object
, &IID_IMFTransform
, (void**) &transform
);
2290 ok(hr
== S_OK
, "Failed to get IMFTransform from transform node's object, hr %#lx.\n", hr
);
2291 IUnknown_Release(node_object
);
2293 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
2294 ok(hr
== S_OK
, "Failed to get transform output type, hr %#lx.\n", hr
);
2296 hr
= IMFMediaType_Compare(output_type
, (IMFAttributes
*)media_type
, MF_ATTRIBUTES_MATCH_OUR_ITEMS
, &ret
);
2297 ok(hr
== S_OK
, "Failed to compare media types, hr %#lx.\n", hr
);
2298 ok(ret
, "Output type of last transform doesn't match sink node type.\n");
2300 IMFTopologyNode_Release(mft_node
);
2301 IMFMediaType_Release(media_type
);
2302 IMFTransform_Release(transform
);
2305 IMFTopologyNode_Release(sink_node2
);
2307 hr
= IMFTopology_SetUINT32(full_topology
, &IID_IMFTopology
, 123);
2308 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2309 hr
= IMFTopoLoader_Load(loader
, full_topology
, &topology2
, NULL
);
2310 ok(hr
== S_OK
, "Failed to resolve topology, hr %#lx.\n", hr
);
2311 ok(full_topology
!= topology2
, "Unexpected instance.\n");
2312 hr
= IMFTopology_GetUINT32(topology2
, &IID_IMFTopology
, &value
);
2313 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2315 IMFTopology_Release(topology2
);
2316 IMFTopology_Release(full_topology
);
2319 hr
= IMFTopology_GetCount(topology
, &count
);
2320 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
2321 ok(!count
, "Unexpected count %u.\n", count
);
2323 IMFActivate_ShutdownObject(sink_activate
);
2324 IMFActivate_Release(sink_activate
);
2327 IMFMediaType_Release(input_type
);
2328 IMFMediaType_Release(output_type
);
2330 IMFMediaSource_Release(source
);
2331 IMFTopoLoader_Release(loader
);
2334 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
2337 static void test_topology_loader_evr(void)
2339 IMFTopologyNode
*node
, *source_node
, *evr_node
;
2340 IMFTopology
*topology
, *full_topology
;
2341 IMFMediaTypeHandler
*handler
;
2342 unsigned int i
, count
, value
;
2343 IMFStreamSink
*stream_sink
;
2344 IMFMediaType
*media_type
;
2345 IMFActivate
*activate
;
2346 IMFTopoLoader
*loader
;
2353 hr
= CoInitialize(NULL
);
2354 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2356 hr
= MFCreateTopoLoader(&loader
);
2357 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2360 hr
= MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE
, &source_node
);
2361 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2363 hr
= MFCreateMediaType(&media_type
);
2364 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2366 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
2367 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2368 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
2369 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2370 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
2371 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2372 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
2373 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2375 init_source_node(media_type
, NULL
, source_node
);
2377 /* EVR sink node. */
2378 window
= create_window();
2380 hr
= MFCreateVideoRendererActivate(window
, &activate
);
2381 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
2383 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
2384 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2386 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
2387 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2389 hr
= MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE
, &evr_node
);
2390 ok(hr
== S_OK
, "Failed to create topology node, hr %#lx.\n", hr
);
2392 hr
= IMFTopologyNode_SetObject(evr_node
, (IUnknown
*)stream_sink
);
2393 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2395 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
2396 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2397 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
2398 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2399 IMFMediaTypeHandler_Release(handler
);
2401 IMFStreamSink_Release(stream_sink
);
2402 IMFMediaSink_Release(sink
);
2404 hr
= MFCreateTopology(&topology
);
2405 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2407 hr
= IMFTopology_AddNode(topology
, source_node
);
2408 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2409 hr
= IMFTopology_AddNode(topology
, evr_node
);
2410 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2411 hr
= IMFTopologyNode_ConnectOutput(source_node
, 0, evr_node
, 0);
2412 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2414 hr
= IMFTopologyNode_SetUINT32(evr_node
, &MF_TOPONODE_CONNECT_METHOD
, MF_CONNECT_DIRECT
);
2415 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2417 hr
= IMFTopologyNode_GetCount(evr_node
, &count
);
2418 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2419 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
2421 hr
= IMFTopoLoader_Load(loader
, topology
, &full_topology
, NULL
);
2422 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2424 hr
= IMFTopology_GetNodeCount(full_topology
, &node_count
);
2425 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2426 ok(node_count
== 3, "Unexpected node count %u.\n", node_count
);
2428 for (i
= 0; i
< node_count
; ++i
)
2430 MF_TOPOLOGY_TYPE node_type
;
2432 hr
= IMFTopology_GetNode(full_topology
, i
, &node
);
2433 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2435 hr
= IMFTopologyNode_GetNodeType(node
, &node_type
);
2436 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2438 if (node_type
== MF_TOPOLOGY_OUTPUT_NODE
)
2441 hr
= IMFTopologyNode_GetUINT32(node
, &MF_TOPONODE_STREAMID
, &value
);
2442 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2443 ok(!value
, "Unexpected stream id %u.\n", value
);
2445 else if (node_type
== MF_TOPOLOGY_SOURCESTREAM_NODE
)
2448 hr
= IMFTopologyNode_GetUINT64(node
, &MF_TOPONODE_MEDIASTART
, &value64
);
2449 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2450 ok(!value64
, "Unexpected value.\n");
2454 IMFTopology_Release(full_topology
);
2456 IMFTopoLoader_Release(loader
);
2458 IMFTopologyNode_Release(source_node
);
2459 IMFTopologyNode_Release(evr_node
);
2460 IMFTopology_Release(topology
);
2461 IMFMediaType_Release(media_type
);
2462 DestroyWindow(window
);
2467 static HRESULT WINAPI
testshutdown_QueryInterface(IMFShutdown
*iface
, REFIID riid
, void **obj
)
2469 if (IsEqualIID(riid
, &IID_IMFShutdown
) ||
2470 IsEqualIID(riid
, &IID_IUnknown
))
2473 IMFShutdown_AddRef(iface
);
2478 return E_NOINTERFACE
;
2481 static ULONG WINAPI
testshutdown_AddRef(IMFShutdown
*iface
)
2486 static ULONG WINAPI
testshutdown_Release(IMFShutdown
*iface
)
2491 static HRESULT WINAPI
testshutdown_Shutdown(IMFShutdown
*iface
)
2496 static HRESULT WINAPI
testshutdown_GetShutdownStatus(IMFShutdown
*iface
, MFSHUTDOWN_STATUS
*status
)
2498 ok(0, "Unexpected call.\n");
2502 static const IMFShutdownVtbl testshutdownvtbl
=
2504 testshutdown_QueryInterface
,
2505 testshutdown_AddRef
,
2506 testshutdown_Release
,
2507 testshutdown_Shutdown
,
2508 testshutdown_GetShutdownStatus
,
2511 static void test_MFShutdownObject(void)
2513 IMFShutdown testshutdown
= { &testshutdownvtbl
};
2514 IUnknown testshutdown2
= { &testservicevtbl
};
2517 hr
= MFShutdownObject(NULL
);
2518 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2520 hr
= MFShutdownObject((IUnknown
*)&testshutdown
);
2521 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2523 hr
= MFShutdownObject(&testshutdown2
);
2524 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2534 static HRESULT WINAPI
test_clock_sink_QueryInterface(IMFClockStateSink
*iface
, REFIID riid
, void **obj
)
2536 if (IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2537 IsEqualIID(riid
, &IID_IUnknown
))
2540 IMFClockStateSink_AddRef(iface
);
2545 return E_NOINTERFACE
;
2548 static ULONG WINAPI
test_clock_sink_AddRef(IMFClockStateSink
*iface
)
2553 static ULONG WINAPI
test_clock_sink_Release(IMFClockStateSink
*iface
)
2558 static HRESULT WINAPI
test_clock_sink_OnClockStart(IMFClockStateSink
*iface
, MFTIME system_time
, LONGLONG offset
)
2563 static HRESULT WINAPI
test_clock_sink_OnClockStop(IMFClockStateSink
*iface
, MFTIME system_time
)
2568 static HRESULT WINAPI
test_clock_sink_OnClockPause(IMFClockStateSink
*iface
, MFTIME system_time
)
2573 static HRESULT WINAPI
test_clock_sink_OnClockRestart(IMFClockStateSink
*iface
, MFTIME system_time
)
2578 static HRESULT WINAPI
test_clock_sink_OnClockSetRate(IMFClockStateSink
*iface
, MFTIME system_time
, float rate
)
2583 static const IMFClockStateSinkVtbl test_clock_sink_vtbl
=
2585 test_clock_sink_QueryInterface
,
2586 test_clock_sink_AddRef
,
2587 test_clock_sink_Release
,
2588 test_clock_sink_OnClockStart
,
2589 test_clock_sink_OnClockStop
,
2590 test_clock_sink_OnClockPause
,
2591 test_clock_sink_OnClockRestart
,
2592 test_clock_sink_OnClockSetRate
,
2595 static void test_presentation_clock(void)
2597 static const struct clock_state_test
2599 enum clock_action action
;
2600 MFCLOCK_STATE clock_state
;
2601 MFCLOCK_STATE source_state
;
2604 clock_state_change
[] =
2606 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
},
2607 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_INVALIDREQUEST
},
2608 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_INVALID
, MF_E_CLOCK_STATE_ALREADY_SET
},
2609 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2610 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2611 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2612 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2613 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2614 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2615 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
},
2616 { CLOCK_STOP
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_CLOCK_STATE_ALREADY_SET
},
2617 { CLOCK_PAUSE
, MFCLOCK_STATE_STOPPED
, MFCLOCK_STATE_STOPPED
, MF_E_INVALIDREQUEST
},
2618 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2619 { CLOCK_PAUSE
, MFCLOCK_STATE_PAUSED
, MFCLOCK_STATE_PAUSED
},
2620 { CLOCK_START
, MFCLOCK_STATE_RUNNING
, MFCLOCK_STATE_RUNNING
},
2622 IMFClockStateSink test_sink
= { &test_clock_sink_vtbl
};
2623 IMFPresentationTimeSource
*time_source
;
2624 MFCLOCK_PROPERTIES props
, props2
;
2625 IMFRateControl
*rate_control
;
2626 IMFPresentationClock
*clock
;
2627 MFSHUTDOWN_STATUS status
;
2628 IMFShutdown
*shutdown
;
2629 MFTIME systime
, time
;
2630 LONGLONG clock_time
;
2631 MFCLOCK_STATE state
;
2638 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
2639 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
2641 hr
= MFCreatePresentationClock(&clock
);
2642 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
2644 check_interface(clock
, &IID_IMFTimer
, TRUE
);
2645 check_interface(clock
, &IID_IMFRateControl
, TRUE
);
2646 check_interface(clock
, &IID_IMFPresentationClock
, TRUE
);
2647 check_interface(clock
, &IID_IMFShutdown
, TRUE
);
2648 check_interface(clock
, &IID_IMFClock
, TRUE
);
2650 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFRateControl
, (void **)&rate_control
);
2651 ok(hr
== S_OK
, "Failed to get rate control interface, hr %#lx.\n", hr
);
2653 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2654 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2656 hr
= IMFPresentationClock_GetTimeSource(clock
, NULL
);
2657 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2659 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2660 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2662 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, NULL
);
2663 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2665 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2666 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2668 hr
= IMFPresentationClock_GetTime(clock
, NULL
);
2669 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
2672 hr
= IMFPresentationClock_GetContinuityKey(clock
, &value
);
2673 ok(hr
== S_OK
, "Failed to get continuity key, hr %#lx.\n", hr
);
2674 ok(value
== 0, "Unexpected value %lu.\n", value
);
2676 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2677 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2679 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2680 ok(hr
== S_OK
, "Failed to get state, hr %#lx.\n", hr
);
2681 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2683 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &clock_time
, &systime
);
2684 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2686 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, NULL
, &systime
);
2687 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2689 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, NULL
);
2690 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2693 hr
= IMFPresentationClock_AddClockStateSink(clock
, NULL
);
2694 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2696 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2697 ok(hr
== S_OK
, "Failed to add a sink, hr %#lx.\n", hr
);
2699 hr
= IMFPresentationClock_AddClockStateSink(clock
, &test_sink
);
2700 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2702 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, NULL
);
2703 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2705 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2706 ok(hr
== S_OK
, "Failed to remove sink, hr %#lx.\n", hr
);
2708 hr
= IMFPresentationClock_RemoveClockStateSink(clock
, &test_sink
);
2709 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2711 /* State change commands, time source is not set yet. */
2712 hr
= IMFPresentationClock_Start(clock
, 0);
2713 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2715 hr
= IMFPresentationClock_Pause(clock
);
2716 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2718 hr
= IMFPresentationClock_Stop(clock
);
2719 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2721 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2722 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
2724 /* Set default time source. */
2725 hr
= MFCreateSystemTimeSource(&time_source
);
2726 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
2728 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &value
);
2729 ok(hr
== S_OK
, "Failed to get time source flags, hr %#lx.\n", hr
);
2730 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2731 "Unexpected clock flags %#lx.\n", value
);
2733 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
2734 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
2736 hr
= IMFPresentationTimeSource_GetProperties(time_source
, &props2
);
2737 ok(hr
== S_OK
, "Failed to get time source properties, hr %#lx.\n", hr
);
2739 hr
= IMFPresentationClock_GetClockCharacteristics(clock
, &value
);
2740 ok(hr
== S_OK
, "Failed to get clock flags, hr %#lx.\n", hr
);
2741 ok(value
== (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
| MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK
),
2742 "Unexpected clock flags %#lx.\n", value
);
2744 hr
= IMFPresentationClock_GetProperties(clock
, &props
);
2745 ok(hr
== S_OK
, "Failed to get clock properties, hr %#lx.\n", hr
);
2746 ok(!memcmp(&props
, &props2
, sizeof(props
)), "Unexpected clock properties.\n");
2748 /* Changing rate at initial state. */
2749 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2750 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2751 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
2753 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2754 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2755 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2756 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2757 ok(rate
== 0.0f
, "Unexpected rate.\n");
2758 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2759 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2761 /* State changes. */
2762 for (i
= 0; i
< ARRAY_SIZE(clock_state_change
); ++i
)
2764 switch (clock_state_change
[i
].action
)
2767 hr
= IMFPresentationClock_Stop(clock
);
2770 hr
= IMFPresentationClock_Pause(clock
);
2773 hr
= IMFPresentationClock_Start(clock
, 0);
2778 ok(hr
== clock_state_change
[i
].hr
, "%u: unexpected hr %#lx.\n", i
, hr
);
2780 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
2781 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
2782 ok(state
== clock_state_change
[i
].source_state
, "%u: unexpected state %d.\n", i
, state
);
2784 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2785 ok(hr
== S_OK
, "%u: failed to get state, hr %#lx.\n", i
, hr
);
2786 ok(state
== clock_state_change
[i
].clock_state
, "%u: unexpected state %d.\n", i
, state
);
2789 /* Clock time stamps. */
2790 hr
= IMFPresentationClock_Start(clock
, 10);
2791 ok(hr
== S_OK
, "Failed to start presentation clock, hr %#lx.\n", hr
);
2793 hr
= IMFPresentationClock_Pause(clock
);
2794 ok(hr
== S_OK
, "Failed to pause presentation clock, hr %#lx.\n", hr
);
2796 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2797 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
2799 hr
= IMFPresentationTimeSource_GetCorrelatedTime(time_source
, 0, &clock_time
, &systime
);
2800 ok(hr
== S_OK
, "Failed to get time source time, hr %#lx.\n", hr
);
2801 ok(time
== clock_time
, "Unexpected clock time.\n");
2803 hr
= IMFPresentationClock_GetCorrelatedTime(clock
, 0, &time
, &systime
);
2804 ok(hr
== S_OK
, "Failed to get clock time, hr %#lx.\n", hr
);
2805 ok(time
== clock_time
, "Unexpected clock time.\n");
2807 IMFPresentationTimeSource_Release(time_source
);
2809 hr
= IMFRateControl_GetRate(rate_control
, NULL
, &rate
);
2810 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2812 hr
= IMFRateControl_GetRate(rate_control
, &thin
, NULL
);
2813 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2815 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2816 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2817 ok(rate
== 1.0f
, "Unexpected rate.\n");
2818 ok(!thin
, "Unexpected thinning.\n");
2820 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2821 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2822 ok(state
== MFCLOCK_STATE_PAUSED
, "Unexpected state %d.\n", state
);
2824 hr
= IMFPresentationClock_Start(clock
, 0);
2825 ok(hr
== S_OK
, "Failed to stop, hr %#lx.\n", hr
);
2827 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2828 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2829 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2830 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2831 ok(rate
== 0.0f
, "Unexpected rate.\n");
2832 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 1.0f
);
2833 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2834 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.0f
);
2835 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2836 hr
= IMFRateControl_SetRate(rate_control
, FALSE
, 0.5f
);
2837 ok(hr
== S_OK
, "Failed to set clock rate, hr %#lx.\n", hr
);
2838 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, -1.0f
);
2839 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2840 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 0.0f
);
2841 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2842 hr
= IMFRateControl_SetRate(rate_control
, TRUE
, 1.0f
);
2843 ok(hr
== MF_E_THINNING_UNSUPPORTED
, "Unexpected hr %#lx.\n", hr
);
2845 hr
= IMFPresentationClock_GetState(clock
, 0, &state
);
2846 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
2847 ok(state
== MFCLOCK_STATE_RUNNING
, "Unexpected state %d.\n", state
);
2849 hr
= IMFRateControl_GetRate(rate_control
, &thin
, &rate
);
2850 ok(hr
== S_OK
, "Failed to get clock rate, hr %#lx.\n", hr
);
2851 ok(rate
== 0.5f
, "Unexpected rate.\n");
2852 ok(!thin
, "Unexpected thinning.\n");
2854 IMFRateControl_Release(rate_control
);
2856 hr
= IMFPresentationClock_QueryInterface(clock
, &IID_IMFShutdown
, (void **)&shutdown
);
2857 ok(hr
== S_OK
, "Failed to get shutdown interface, hr %#lx.\n", hr
);
2859 /* Shutdown behavior. */
2860 hr
= IMFShutdown_GetShutdownStatus(shutdown
, NULL
);
2861 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
2863 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2864 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
2866 hr
= IMFShutdown_Shutdown(shutdown
);
2867 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2870 hr
= IMFPresentationClock_GetTimeSource(clock
, &time_source
);
2871 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2872 ok(!!time_source
, "Unexpected instance %p.\n", time_source
);
2873 IMFPresentationTimeSource_Release(time_source
);
2875 hr
= IMFPresentationClock_GetTime(clock
, &time
);
2876 ok(hr
== S_OK
, "Failed to get time, hr %#lx.\n", hr
);
2878 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2879 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
2880 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2882 hr
= IMFPresentationClock_Start(clock
, 0);
2883 ok(hr
== S_OK
, "Failed to start the clock, hr %#lx.\n", hr
);
2885 hr
= IMFShutdown_GetShutdownStatus(shutdown
, &status
);
2886 ok(hr
== S_OK
, "Failed to get status, hr %#lx.\n", hr
);
2887 ok(status
== MFSHUTDOWN_COMPLETED
, "Unexpected status.\n");
2889 hr
= IMFShutdown_Shutdown(shutdown
);
2890 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2892 IMFShutdown_Release(shutdown
);
2894 IMFPresentationClock_Release(clock
);
2897 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
2900 static HRESULT WINAPI
grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback
*iface
, REFIID riid
, void **obj
)
2902 if (IsEqualIID(riid
, &IID_IMFSampleGrabberSinkCallback
) ||
2903 IsEqualIID(riid
, &IID_IMFClockStateSink
) ||
2904 IsEqualIID(riid
, &IID_IUnknown
))
2907 IMFSampleGrabberSinkCallback_AddRef(iface
);
2912 return E_NOINTERFACE
;
2915 static ULONG WINAPI
grabber_callback_AddRef(IMFSampleGrabberSinkCallback
*iface
)
2920 static ULONG WINAPI
grabber_callback_Release(IMFSampleGrabberSinkCallback
*iface
)
2925 static HRESULT WINAPI
grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, LONGLONG offset
)
2930 static HRESULT WINAPI
grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2935 static HRESULT WINAPI
grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2940 static HRESULT WINAPI
grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
)
2945 static HRESULT WINAPI
grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback
*iface
, MFTIME time
, float rate
)
2950 static HRESULT WINAPI
grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback
*iface
,
2951 IMFPresentationClock
*clock
)
2956 static HRESULT WINAPI
grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback
*iface
, REFGUID major_type
,
2957 DWORD sample_flags
, LONGLONG sample_time
, LONGLONG sample_duration
, const BYTE
*buffer
, DWORD sample_size
)
2962 static HRESULT WINAPI
grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback
*iface
)
2967 static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl
=
2969 grabber_callback_QueryInterface
,
2970 grabber_callback_AddRef
,
2971 grabber_callback_Release
,
2972 grabber_callback_OnClockStart
,
2973 grabber_callback_OnClockStop
,
2974 grabber_callback_OnClockPause
,
2975 grabber_callback_OnClockRestart
,
2976 grabber_callback_OnClockSetRate
,
2977 grabber_callback_OnSetPresentationClock
,
2978 grabber_callback_OnProcessSample
,
2979 grabber_callback_OnShutdown
,
2982 static IMFSampleGrabberSinkCallback grabber_callback
= { &grabber_callback_vtbl
};
2984 static void test_sample_grabber(void)
2986 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
2987 IMFMediaTypeHandler
*handler
, *handler2
;
2988 IMFPresentationTimeSource
*time_source
;
2989 IMFPresentationClock
*clock
, *clock2
;
2990 IMFStreamSink
*stream
, *stream2
;
2991 IMFRateSupport
*rate_support
;
2992 IMFMediaEventGenerator
*eg
;
2993 IMFMediaSink
*sink
, *sink2
;
2994 DWORD flags
, count
, id
;
2995 IMFActivate
*activate
;
2996 IMFMediaEvent
*event
;
3004 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3005 ok(hr
== S_OK
, "Failed to start up, hr %#lx.\n", hr
);
3007 hr
= MFCreateMediaType(&media_type
);
3008 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3010 hr
= MFCreateSampleGrabberSinkActivate(NULL
, NULL
, &activate
);
3011 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3013 hr
= MFCreateSampleGrabberSinkActivate(NULL
, &grabber_callback
, &activate
);
3014 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3016 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3017 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3018 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3019 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3021 EXPECT_REF(media_type
, 1);
3022 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3023 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3024 EXPECT_REF(media_type
, 2);
3026 hr
= IMFActivate_GetCount(activate
, &attr_count
);
3027 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
3028 ok(!attr_count
, "Unexpected count %u.\n", attr_count
);
3030 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3031 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3033 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
3034 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
3035 check_interface(sink
, &IID_IMFGetService
, TRUE
);
3036 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
3037 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
3039 if (SUCCEEDED(MFGetService((IUnknown
*)sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, (void **)&rate_support
)))
3041 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3042 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3043 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
3045 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3046 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3047 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
3049 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3050 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3051 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
3053 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3054 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3055 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
3057 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
3058 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3059 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3061 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
3062 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3063 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3065 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
3066 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3067 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3069 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
3070 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3071 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
3073 hr
= IMFRateSupport_IsRateSupported(rate_support
, TRUE
, 1.0f
, &rate
);
3074 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3075 ok(rate
== 1.0f
, "Unexpected rate %f.\n", rate
);
3077 IMFRateSupport_Release(rate_support
);
3080 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3081 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3082 ok(flags
& MEDIASINK_FIXED_STREAMS
, "Unexpected flags %#lx.\n", flags
);
3084 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3085 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
3086 ok(count
== 1, "Unexpected stream count %lu.\n", count
);
3088 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3089 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
3091 check_interface(stream
, &IID_IMFMediaEventGenerator
, TRUE
);
3092 check_interface(stream
, &IID_IMFMediaTypeHandler
, TRUE
);
3094 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3095 ok(hr
== S_OK
, "Failed to get stream id, hr %#lx.\n", hr
);
3096 ok(id
== 0, "Unexpected id %#lx.\n", id
);
3098 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3099 ok(hr
== S_OK
, "Failed to get media sink, hr %lx.\n", hr
);
3100 ok(sink2
== sink
, "Unexpected sink.\n");
3101 IMFMediaSink_Release(sink2
);
3103 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 1, &stream2
);
3104 ok(hr
== MF_E_INVALIDINDEX
, "Unexpected hr %#lx.\n", hr
);
3106 hr
= IMFMediaSink_GetStreamSinkById(sink
, 1, &stream2
);
3107 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3109 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3110 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3112 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
3113 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3115 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
3116 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
3118 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
3120 /* Event generator. */
3121 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFMediaEventGenerator
, (void **)&eg
);
3122 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
3124 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3125 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3127 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&unk
);
3128 ok(hr
== E_NOINTERFACE
, "Unexpected hr %#lx.\n", hr
);
3130 hr
= IMFStreamSink_QueryInterface(stream
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
3131 ok(hr
== S_OK
, "Failed to get handler interface, hr %#lx.\n", hr
);
3133 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3134 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3135 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3136 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3137 ok(count
== 0, "Unexpected count %lu.\n", count
);
3138 ok(handler
== handler2
, "Unexpected handler.\n");
3140 IMFMediaTypeHandler_Release(handler
);
3141 IMFMediaTypeHandler_Release(handler2
);
3144 hr
= MFCreatePresentationClock(&clock
);
3145 ok(hr
== S_OK
, "Failed to create clock object, hr %#lx.\n", hr
);
3147 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
3148 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3150 hr
= IMFMediaSink_GetPresentationClock(sink
, &clock2
);
3151 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
3153 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
3154 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3156 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
3157 ok(hr
== S_OK
, "Failed to set presentation clock, hr %#lx.\n", hr
);
3159 hr
= MFCreateSystemTimeSource(&time_source
);
3160 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
3162 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
3163 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
3164 IMFPresentationTimeSource_Release(time_source
);
3166 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3167 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3169 hr
= IMFActivate_ShutdownObject(activate
);
3170 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3172 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3173 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3175 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3176 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3178 /* On Win8+ this initialization happens automatically. */
3179 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3180 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3182 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
3183 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3185 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3186 ok(hr
== S_OK
, "Failed to get media type count, hr %#lx.\n", hr
);
3187 ok(count
== 0, "Unexpected count %lu.\n", count
);
3189 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3190 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
3191 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid
));
3193 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
3194 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3195 ok(media_type2
== media_type
, "Unexpected media type.\n");
3196 IMFMediaType_Release(media_type2
);
3198 hr
= MFCreateMediaType(&media_type2
);
3199 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3201 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3202 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3204 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3205 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3207 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3208 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3210 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_Float
);
3211 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3213 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3214 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3216 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3217 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3219 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3220 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3222 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3223 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3224 IMFMediaType_Release(media_type
);
3226 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3227 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3229 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3230 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3231 ok(media_type2
== media_type
, "Unexpected media type.\n");
3232 IMFMediaType_Release(media_type
);
3234 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3235 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3237 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, NULL
);
3238 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3240 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3241 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3243 hr
= MFCreateMediaType(&media_type
);
3244 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3246 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3247 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3249 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
3250 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3252 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3253 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3255 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3256 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3258 media_type3
= (void *)0xdeadbeef;
3259 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3260 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3261 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3263 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_FIXED_SIZE_SAMPLES
, 1);
3264 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3266 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_SAMPLE_SIZE
, 1024);
3267 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3269 media_type3
= (void *)0xdeadbeef;
3270 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3271 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3272 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3274 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3275 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3277 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3278 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3280 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3281 ok(hr
== MF_E_NO_EVENTS_AVAILABLE
, "Unexpected hr %#lx.\n", hr
);
3283 EXPECT_REF(clock
, 3);
3284 hr
= IMFMediaSink_Shutdown(sink
);
3285 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3286 EXPECT_REF(clock
, 1);
3288 hr
= IMFMediaEventGenerator_GetEvent(eg
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3289 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3291 hr
= IMFMediaSink_Shutdown(sink
);
3292 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3294 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3295 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3297 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream2
);
3298 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3300 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
3301 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3303 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream2
);
3304 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3306 hr
= IMFStreamSink_GetEvent(stream
, MF_EVENT_FLAG_NO_WAIT
, &event
);
3307 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3309 hr
= IMFStreamSink_GetMediaSink(stream
, &sink2
);
3310 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3313 hr
= IMFStreamSink_GetIdentifier(stream
, &id
);
3314 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3315 ok(id
== 1, "Unexpected id %lu.\n", id
);
3317 media_type3
= (void *)0xdeadbeef;
3318 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type3
);
3319 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3320 ok(media_type3
== (void *)0xdeadbeef, "Unexpected media type %p.\n", media_type3
);
3322 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
3323 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3325 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
3326 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3328 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
3329 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
3331 IMFMediaType_Release(media_type2
);
3332 IMFMediaType_Release(media_type
);
3334 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type
);
3335 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3337 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
3338 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3340 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
3341 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3343 hr
= IMFMediaTypeHandler_GetMajorType(handler
, NULL
);
3344 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3346 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3347 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3349 IMFMediaTypeHandler_Release(handler
);
3351 handler
= (void *)0xdeadbeef;
3352 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3353 ok(hr
== MF_E_STREAMSINK_REMOVED
, "Unexpected hr %#lx.\n", hr
);
3354 ok(handler
== (void *)0xdeadbeef, "Unexpected pointer.\n");
3356 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, NULL
);
3357 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3359 IMFMediaEventGenerator_Release(eg
);
3360 IMFMediaSink_Release(sink
);
3361 IMFStreamSink_Release(stream
);
3363 refcount
= IMFActivate_Release(activate
);
3364 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
3366 /* Rateless mode with MF_SAMPLEGRABBERSINK_IGNORE_CLOCK. */
3367 hr
= MFCreateMediaType(&media_type
);
3368 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3370 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3371 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3372 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3373 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3375 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3376 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3378 hr
= IMFActivate_SetUINT32(activate
, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK
, 1);
3379 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3381 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3382 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3384 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
3385 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
3386 ok(flags
& MEDIASINK_RATELESS
, "Unexpected flags %#lx.\n", flags
);
3388 hr
= IMFActivate_ShutdownObject(activate
);
3389 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3391 hr
= IMFMediaSink_Shutdown(sink
);
3392 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3394 IMFMediaSink_Release(sink
);
3397 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3398 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3400 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3401 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3402 IMFMediaSink_Release(sink
);
3404 hr
= IMFActivate_ShutdownObject(activate
);
3405 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3407 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3408 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3410 hr
= IMFActivate_GetCount(activate
, &attr_count
);
3411 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3413 hr
= IMFActivate_DetachObject(activate
);
3414 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3416 IMFActivate_Release(activate
);
3418 IMFMediaType_Release(media_type
);
3419 IMFPresentationClock_Release(clock
);
3422 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
3425 static void test_sample_grabber_is_mediatype_supported(void)
3427 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
3428 IMFMediaTypeHandler
*handler
;
3429 IMFActivate
*activate
;
3430 IMFStreamSink
*stream
;
3436 /* IsMediaTypeSupported checks are done against the creation type, and check format data */
3437 hr
= MFCreateMediaType(&media_type
);
3438 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3440 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3441 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3442 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3443 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3444 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3445 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3447 hr
= MFCreateSampleGrabberSinkActivate(media_type
, &grabber_callback
, &activate
);
3448 ok(hr
== S_OK
, "Failed to create grabber activate, hr %#lx.\n", hr
);
3450 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
3451 ok(hr
== S_OK
, "Failed to activate object, hr %#lx.\n", hr
);
3453 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream
);
3454 ok(hr
== S_OK
, "Failed to get sink stream, hr %#lx.\n", hr
);
3455 hr
= IMFStreamSink_GetMediaTypeHandler(stream
, &handler
);
3456 ok(hr
== S_OK
, "Failed to get type handler, hr %#lx.\n", hr
);
3457 IMFStreamSink_Release(stream
);
3459 IMFMediaSink_Release(sink
);
3461 /* On Win8+ this initialization happens automatically. */
3462 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
3463 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3465 hr
= MFCreateMediaType(&media_type2
);
3466 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3468 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
3469 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3470 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_SUBTYPE
, &MFAudioFormat_PCM
);
3471 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3472 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3473 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3475 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3476 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3478 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3479 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Failed to set media type, hr %#lx.\n", hr
);
3481 /* Make it match grabber type sample rate. */
3482 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100);
3483 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3485 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3486 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3488 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type2
);
3489 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3490 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type3
);
3491 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
3492 ok(media_type3
== media_type2
, "Unexpected media type instance.\n");
3493 IMFMediaType_Release(media_type3
);
3495 /* Change original type. */
3496 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3497 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3499 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3500 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
3502 hr
= IMFMediaType_SetUINT32(media_type2
, &MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000);
3503 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3505 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type2
, NULL
);
3506 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3508 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3509 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3510 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3512 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3513 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3515 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
3516 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3517 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected major type.\n");
3519 IMFMediaType_Release(media_type2
);
3520 IMFMediaType_Release(media_type
);
3522 IMFMediaTypeHandler_Release(handler
);
3524 refcount
= IMFActivate_Release(activate
);
3525 ok(!refcount
, "Unexpected refcount %lu.\n", refcount
);
3528 static BOOL
is_supported_video_type(const GUID
*guid
)
3530 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
3531 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
3532 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
3533 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
3534 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
3535 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
3536 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
3537 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
3538 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
3539 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
3540 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
3541 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
3542 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
3543 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
3544 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
3545 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
3546 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
3547 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
3548 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
3549 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
3550 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
3551 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
3552 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
3553 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
3554 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
3555 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
3556 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
3557 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
3558 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
3559 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
3560 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
3563 static void test_video_processor(void)
3565 const GUID transform_inputs
[22] =
3571 MFVideoFormat_ARGB32
,
3572 MFVideoFormat_RGB32
,
3577 MFVideoFormat_RGB24
,
3578 MFVideoFormat_RGB555
,
3579 MFVideoFormat_RGB565
,
3590 const GUID transform_outputs
[21] =
3596 MFVideoFormat_ARGB32
,
3597 MFVideoFormat_RGB32
,
3602 MFVideoFormat_RGB24
,
3603 MFVideoFormat_RGB555
,
3604 MFVideoFormat_RGB565
,
3614 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3615 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
3616 DWORD input_count
, output_count
, input_id
, output_id
, flags
;
3617 DWORD input_min
, input_max
, output_min
, output_max
, i
;
3618 IMFAttributes
*attributes
, *attributes2
;
3619 IMFMediaType
*media_type
, *media_type2
;
3620 MFT_OUTPUT_DATA_BUFFER output_buffer
;
3621 MFT_OUTPUT_STREAM_INFO output_info
;
3622 MFT_INPUT_STREAM_INFO input_info
;
3623 IMFSample
*sample
, *sample2
;
3624 IMFTransform
*transform
;
3625 IMFMediaBuffer
*buffer
;
3626 IMFMediaEvent
*event
;
3633 hr
= CoInitialize(NULL
);
3634 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3636 if (!create_transform(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, L
"Microsoft Video Processor MFT", &MFMediaType_Video
,
3637 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
3638 &transform
, &CLSID_VideoProcessorMFT
, &class_id
))
3640 has_video_processor
= TRUE
;
3643 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
3645 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
3646 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
3647 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
3649 /* Transform global attributes. */
3650 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3651 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3653 hr
= IMFAttributes_GetCount(attributes
, &count
);
3654 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3656 ok(!!count
, "Unexpected attribute count %u.\n", count
);
3659 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D11_AWARE
, &value
);
3661 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3662 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
3664 hr
= IMFTransform_GetAttributes(transform
, &attributes2
);
3665 ok(hr
== S_OK
, "Failed to get attributes, hr %#lx.\n", hr
);
3666 ok(attributes
== attributes2
, "Unexpected instance.\n");
3667 IMFAttributes_Release(attributes
);
3668 IMFAttributes_Release(attributes2
);
3670 hr
= IMFTransform_GetStreamLimits(transform
, &input_min
, &input_max
, &output_min
, &output_max
);
3671 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
3672 ok(input_min
== input_max
&& input_min
== 1 && output_min
== output_max
&& output_min
== 1,
3673 "Unexpected stream limits.\n");
3675 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
3676 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
3677 ok(input_count
== 1 && output_count
== 1, "Unexpected stream count %lu, %lu.\n", input_count
, output_count
);
3679 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
3680 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3683 hr
= IMFTransform_AddInputStreams(transform
, 1, &input_id
);
3684 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3686 hr
= IMFTransform_DeleteInputStream(transform
, 0);
3687 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3689 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3691 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3693 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
3694 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3696 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
3698 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3700 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
3701 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3702 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes2
);
3703 ok(hr
== S_OK
, "Failed to get output attributes, hr %#lx.\n", hr
);
3704 ok(attributes
== attributes2
, "Unexpected instance.\n");
3705 IMFAttributes_Release(attributes
);
3706 IMFAttributes_Release(attributes2
);
3708 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3710 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3712 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type
);
3714 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3716 hr
= IMFTransform_GetInputCurrentType(transform
, 1, &media_type
);
3718 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3720 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
3722 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3724 hr
= IMFTransform_GetOutputCurrentType(transform
, 1, &media_type
);
3726 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3728 hr
= IMFTransform_GetInputStreamInfo(transform
, 1, &input_info
);
3730 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
3732 memset(&input_info
, 0xcc, sizeof(input_info
));
3733 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3735 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3736 ok(input_info
.dwFlags
== 0, "Unexpected flag %#lx.\n", input_info
.dwFlags
);
3737 ok(input_info
.cbSize
== 0, "Unexpected size %lu.\n", input_info
.cbSize
);
3738 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
3739 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
3741 hr
= MFCreateMediaEvent(MEUnknown
, &GUID_NULL
, S_OK
, NULL
, &event
);
3742 ok(hr
== S_OK
, "Failed to create event object, hr %#lx.\n", hr
);
3743 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
3744 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3745 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
3746 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
3747 IMFMediaEvent_Release(event
);
3749 /* Configure stream types. */
3752 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
3755 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
3759 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
3760 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
3761 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3762 IMFMediaType_Release(media_type2
);
3764 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
3765 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
3766 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
3768 hr
= IMFMediaType_GetCount(media_type
, &count
);
3769 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
3770 ok(count
== 2, "Unexpected count %u.\n", count
);
3772 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
3773 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
3774 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
3776 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3777 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
3779 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3780 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
3782 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
3783 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
3785 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
3786 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
3787 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
3788 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
3790 IMFMediaType_Release(media_type
);
3794 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3795 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3797 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
3798 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
3800 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3801 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
3803 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
3804 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
3805 ok(media_type
!= media_type2
, "Unexpected instance.\n");
3806 IMFMediaType_Release(media_type2
);
3808 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3809 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
3810 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
3812 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
3813 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3814 ok(input_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
3815 ok(input_info
.cbMaxLookahead
== 0, "Unexpected lookahead length %lu.\n", input_info
.cbMaxLookahead
);
3816 ok(input_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
3818 IMFMediaType_Release(media_type
);
3822 hr
= MFCreateMediaType(&media_type
);
3823 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
3825 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
3826 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3828 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
3829 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3831 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
3832 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3834 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
3836 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
3838 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
3839 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
3841 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3843 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
3845 memset(&output_info
, 0, sizeof(output_info
));
3846 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
3848 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
3849 ok(output_info
.dwFlags
== 0, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
3851 ok(output_info
.cbSize
> 0, "Unexpected size %lu.\n", output_info
.cbSize
);
3852 ok(output_info
.cbAlignment
== 0, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
3854 hr
= MFCreateSample(&sample
);
3855 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
3857 hr
= MFCreateSample(&sample2
);
3858 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
3860 memset(&output_buffer
, 0, sizeof(output_buffer
));
3861 output_buffer
.pSample
= sample
;
3863 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3865 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
3866 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3867 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3869 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3871 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
3873 hr
= IMFTransform_ProcessInput(transform
, 0, sample2
, 0);
3875 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
3877 memset(&output_buffer
, 0, sizeof(output_buffer
));
3878 output_buffer
.pSample
= sample
;
3880 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3882 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
3883 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3884 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3886 hr
= IMFSample_SetSampleTime(sample2
, 0);
3887 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
3888 memset(&output_buffer
, 0, sizeof(output_buffer
));
3889 output_buffer
.pSample
= sample
;
3891 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3893 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
3894 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3895 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3897 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
3898 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
3900 hr
= IMFSample_AddBuffer(sample2
, buffer
);
3901 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
3903 hr
= IMFSample_AddBuffer(sample
, buffer
);
3904 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
3906 memset(&output_buffer
, 0, sizeof(output_buffer
));
3907 output_buffer
.pSample
= sample
;
3909 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3911 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
3912 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3913 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3917 memset(&output_buffer
, 0, sizeof(output_buffer
));
3918 output_buffer
.pSample
= sample
;
3920 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output_buffer
, &flags
);
3921 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
3922 ok(output_buffer
.dwStatus
== 0, "Unexpected buffer status, %#lx.\n", output_buffer
.dwStatus
);
3923 ok(flags
== 0, "Unexpected status %#lx.\n", flags
);
3926 IMFSample_Release(sample2
);
3927 IMFSample_Release(sample
);
3928 IMFMediaBuffer_Release(buffer
);
3930 IMFMediaType_Release(media_type
);
3932 IMFTransform_Release(transform
);
3938 static void test_quality_manager(void)
3940 IMFPresentationClock
*clock
;
3941 IMFQualityManager
*manager
;
3942 IMFTopology
*topology
;
3945 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
3946 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
3948 hr
= MFCreatePresentationClock(&clock
);
3949 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
3951 hr
= MFCreateStandardQualityManager(&manager
);
3952 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3954 check_interface(manager
, &IID_IMFQualityManager
, TRUE
);
3955 check_interface(manager
, &IID_IMFClockStateSink
, TRUE
);
3957 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3958 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
3960 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3961 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3963 /* Set clock, then shutdown. */
3964 EXPECT_REF(clock
, 1);
3965 EXPECT_REF(manager
, 1);
3966 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3967 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3968 EXPECT_REF(clock
, 2);
3969 EXPECT_REF(manager
, 2);
3971 hr
= IMFQualityManager_Shutdown(manager
);
3972 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3973 EXPECT_REF(clock
, 1);
3975 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3976 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3978 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
3979 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3981 hr
= IMFQualityManager_NotifyPresentationClock(manager
, NULL
);
3982 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
3984 hr
= IMFQualityManager_Shutdown(manager
);
3985 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3987 IMFQualityManager_Release(manager
);
3989 /* Set clock, then release without shutting down. */
3990 hr
= MFCreateStandardQualityManager(&manager
);
3991 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
3993 EXPECT_REF(clock
, 1);
3994 hr
= IMFQualityManager_NotifyPresentationClock(manager
, clock
);
3995 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
3996 EXPECT_REF(clock
, 2);
3998 IMFQualityManager_Release(manager
);
3999 EXPECT_REF(clock
, 2);
4001 IMFPresentationClock_Release(clock
);
4004 hr
= MFCreateStandardQualityManager(&manager
);
4005 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4007 hr
= MFCreateTopology(&topology
);
4008 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4010 EXPECT_REF(topology
, 1);
4011 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4012 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4013 EXPECT_REF(topology
, 2);
4015 hr
= IMFQualityManager_NotifyTopology(manager
, NULL
);
4016 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4017 EXPECT_REF(topology
, 1);
4019 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4020 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4022 EXPECT_REF(topology
, 2);
4023 hr
= IMFQualityManager_Shutdown(manager
);
4024 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4025 EXPECT_REF(topology
, 1);
4027 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4028 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4030 IMFQualityManager_Release(manager
);
4032 hr
= MFCreateStandardQualityManager(&manager
);
4033 ok(hr
== S_OK
, "Failed to create quality manager, hr %#lx.\n", hr
);
4035 EXPECT_REF(topology
, 1);
4036 hr
= IMFQualityManager_NotifyTopology(manager
, topology
);
4037 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4038 EXPECT_REF(topology
, 2);
4040 IMFQualityManager_Release(manager
);
4041 EXPECT_REF(topology
, 1);
4043 IMFTopology_Release(topology
);
4046 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4049 static void check_sar_rate_support(IMFMediaSink
*sink
)
4051 IMFRateSupport
*rate_support
;
4052 IMFMediaTypeHandler
*handler
;
4053 IMFStreamSink
*stream_sink
;
4054 IMFMediaType
*media_type
;
4058 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rate_support
);
4060 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4061 if (FAILED(hr
)) return;
4063 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
4064 if (hr
== MF_E_SHUTDOWN
)
4066 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4067 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4069 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4070 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4072 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4073 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4075 IMFRateSupport_Release(rate_support
);
4078 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4080 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
4081 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4083 IMFStreamSink_Release(stream_sink
);
4085 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4086 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4088 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, NULL
);
4089 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4091 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
4094 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4095 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4097 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4098 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4100 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4101 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4103 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4104 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4106 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4107 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4109 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4110 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4112 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4113 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4115 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4116 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4118 IMFMediaType_Release(media_type
);
4122 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4123 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4125 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4126 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4128 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4129 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4131 hr
= IMFRateSupport_GetSlowestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4132 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4134 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, FALSE
, &rate
);
4135 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4137 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_FORWARD
, TRUE
, &rate
);
4138 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4140 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, FALSE
, &rate
);
4141 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4143 hr
= IMFRateSupport_GetFastestRate(rate_support
, MFRATE_REVERSE
, TRUE
, &rate
);
4144 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4147 IMFMediaTypeHandler_Release(handler
);
4148 IMFRateSupport_Release(rate_support
);
4151 static void test_sar(void)
4153 IMFPresentationClock
*present_clock
, *present_clock2
;
4154 IMFMediaType
*mediatype
, *mediatype2
, *mediatype3
;
4155 IMFClockStateSink
*state_sink
, *state_sink2
;
4156 IMFMediaTypeHandler
*handler
, *handler2
;
4157 IMFPresentationTimeSource
*time_source
;
4158 IMFSimpleAudioVolume
*simple_volume
;
4159 IMFAudioStreamVolume
*stream_volume
;
4160 IMFMediaSink
*sink
, *sink2
;
4161 IMFStreamSink
*stream_sink
;
4162 IMFAttributes
*attributes
;
4163 DWORD i
, id
, flags
, count
;
4164 IMFActivate
*activate
;
4165 UINT32 channel_count
;
4166 MFCLOCK_STATE state
;
4174 hr
= CoInitialize(NULL
);
4175 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4177 hr
= MFCreateAudioRenderer(NULL
, &sink
);
4178 if (hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
)
4180 skip("No audio playback device available.\n");
4184 ok(hr
== S_OK
, "Failed to create renderer, hr %#lx.\n", hr
);
4186 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4187 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4189 hr
= MFCreatePresentationClock(&present_clock
);
4190 ok(hr
== S_OK
, "Failed to create presentation clock, hr %#lx.\n", hr
);
4192 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFPresentationTimeSource
, (void **)&time_source
);
4194 ok(hr
== S_OK
, "Failed to get time source interface, hr %#lx.\n", hr
);
4198 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink2
);
4199 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4200 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4201 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4202 ok(state_sink
== state_sink2
, "Unexpected clock sink.\n");
4203 IMFClockStateSink_Release(state_sink2
);
4204 IMFClockStateSink_Release(state_sink
);
4206 hr
= IMFPresentationTimeSource_GetUnderlyingClock(time_source
, &clock
);
4207 ok(hr
== MF_E_NO_CLOCK
, "Unexpected hr %#lx.\n", hr
);
4209 hr
= IMFPresentationTimeSource_GetClockCharacteristics(time_source
, &flags
);
4210 ok(hr
== S_OK
, "Failed to get flags, hr %#lx.\n", hr
);
4211 ok(flags
== MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ
, "Unexpected flags %#lx.\n", flags
);
4213 hr
= IMFPresentationTimeSource_GetState(time_source
, 0, &state
);
4214 ok(hr
== S_OK
, "Failed to get clock state, hr %#lx.\n", hr
);
4215 ok(state
== MFCLOCK_STATE_INVALID
, "Unexpected state %d.\n", state
);
4217 hr
= IMFPresentationTimeSource_QueryInterface(time_source
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4218 ok(hr
== S_OK
, "Failed to get state sink, hr %#lx.\n", hr
);
4220 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4221 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4223 IMFClockStateSink_Release(state_sink
);
4225 IMFPresentationTimeSource_Release(time_source
);
4227 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4228 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4230 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4231 ok(hr
== MF_E_STREAMSINKS_FIXED
, "Unexpected hr %#lx.\n", hr
);
4233 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4234 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4236 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4237 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4238 ok(count
== 1, "Unexpected count %lu.\n", count
);
4240 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4241 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4242 ok(flags
== (MEDIASINK_FIXED_STREAMS
| MEDIASINK_CAN_PREROLL
), "Unexpected flags %#lx.\n", flags
);
4244 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4245 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4246 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4247 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4248 todo_wine
check_interface(sink
, &IID_IMFPresentationTimeSource
, TRUE
);
4249 todo_wine
check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4250 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateControl
, FALSE
);
4251 check_service_interface(sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, TRUE
);
4252 check_service_interface(sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, TRUE
);
4255 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4256 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4258 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4259 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4261 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4262 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4264 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4265 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4267 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4268 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4270 IMFClockStateSink_Release(state_sink
);
4272 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4273 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4275 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4277 ok(hr
== MF_E_CLOCK_NO_TIME_SOURCE
, "Unexpected hr %#lx.\n", hr
);
4279 hr
= MFCreateSystemTimeSource(&time_source
);
4280 ok(hr
== S_OK
, "Failed to create time source, hr %#lx.\n", hr
);
4282 hr
= IMFPresentationClock_SetTimeSource(present_clock
, time_source
);
4283 ok(hr
== S_OK
, "Failed to set time source, hr %#lx.\n", hr
);
4284 IMFPresentationTimeSource_Release(time_source
);
4286 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4287 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4289 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4290 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4292 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4293 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4294 ok(present_clock
== present_clock2
, "Unexpected instance.\n");
4295 IMFPresentationClock_Release(present_clock2
);
4298 hr
= IMFMediaSink_GetStreamSinkByIndex(sink
, 0, &stream_sink
);
4299 ok(hr
== S_OK
, "Failed to get a stream, hr %#lx.\n", hr
);
4301 check_interface(stream_sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4302 check_interface(stream_sink
, &IID_IMFMediaTypeHandler
, TRUE
);
4303 todo_wine
check_interface(stream_sink
, &IID_IMFGetService
, TRUE
);
4305 hr
= IMFStreamSink_GetIdentifier(stream_sink
, &id
);
4306 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4307 ok(!id
, "Unexpected id.\n");
4309 hr
= IMFStreamSink_GetMediaSink(stream_sink
, &sink2
);
4310 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4311 ok(sink
== sink2
, "Unexpected object.\n");
4312 IMFMediaSink_Release(sink2
);
4314 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &handler
);
4315 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4317 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFMediaTypeHandler
, (void **)&handler2
);
4318 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4319 ok(handler2
== handler
, "Unexpected instance.\n");
4320 IMFMediaTypeHandler_Release(handler2
);
4322 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
4323 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4324 ok(IsEqualGUID(&guid
, &MFMediaType_Audio
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4327 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
4328 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
4329 ok(!!count
, "Unexpected type count %lu.\n", count
);
4331 /* A number of same major/subtype entries are returned, with different degrees of finer format
4332 details. Some incomplete types are not accepted, check that at least one of them is considered supported. */
4334 for (i
= 0, found
= -1; i
< count
; ++i
)
4336 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, i
, &mediatype
);
4337 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4339 if (SUCCEEDED(IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
)))
4341 IMFMediaType_Release(mediatype
);
4343 if (found
!= -1) break;
4345 ok(found
!= -1, "Haven't found a supported type.\n");
4347 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4348 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4350 hr
= MFCreateMediaType(&mediatype
);
4351 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4353 /* Actual return value is MF_E_ATRIBUTENOTFOUND triggered by missing MF_MT_MAJOR_TYPE */
4354 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4355 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4357 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4358 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4359 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4360 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4362 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
4363 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4364 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype
, NULL
);
4365 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4367 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype
);
4368 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4370 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype2
);
4371 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4373 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, found
, &mediatype3
);
4374 ok(hr
== S_OK
, "Failed to get media type, hr %#lx.\n", hr
);
4375 ok(mediatype2
== mediatype3
, "Unexpected instance.\n");
4376 IMFMediaType_Release(mediatype3
);
4378 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, mediatype2
, NULL
);
4379 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4381 IMFMediaType_Release(mediatype
);
4383 check_sar_rate_support(sink
);
4385 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, mediatype2
);
4386 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4388 check_sar_rate_support(sink
);
4390 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &mediatype
);
4391 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4392 ok(mediatype
== mediatype2
, "Unexpected instance.\n");
4393 IMFMediaType_Release(mediatype
);
4395 IMFMediaType_Release(mediatype2
);
4397 /* Reset back to uninitialized state. */
4398 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
4399 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4401 IMFMediaTypeHandler_Release(handler
);
4403 /* State change with initialized stream. */
4404 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFClockStateSink
, (void **)&state_sink
);
4405 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4407 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4408 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4410 hr
= IMFClockStateSink_OnClockStart(state_sink
, 0, 0);
4411 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4413 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4414 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4416 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4417 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4419 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4420 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4422 hr
= IMFClockStateSink_OnClockPause(state_sink
, 0);
4423 ok(hr
== MF_E_INVALID_STATE_TRANSITION
, "Unexpected hr %#lx.\n", hr
);
4425 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4426 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4428 hr
= IMFClockStateSink_OnClockRestart(state_sink
, 0);
4429 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4431 hr
= IMFClockStateSink_OnClockStop(state_sink
, 0);
4432 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4434 IMFClockStateSink_Release(state_sink
);
4436 IMFStreamSink_Release(stream_sink
);
4438 /* Volume control */
4439 hr
= MFGetService((IUnknown
*)sink
, &MR_POLICY_VOLUME_SERVICE
, &IID_IMFSimpleAudioVolume
, (void **)&simple_volume
);
4440 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4442 hr
= IMFSimpleAudioVolume_GetMute(simple_volume
, &mute
);
4443 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4445 IMFSimpleAudioVolume_Release(simple_volume
);
4447 hr
= MFGetService((IUnknown
*)sink
, &MR_STREAM_VOLUME_SERVICE
, &IID_IMFAudioStreamVolume
, (void **)&stream_volume
);
4448 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4450 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, &channel_count
);
4451 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4453 hr
= IMFAudioStreamVolume_GetChannelCount(stream_volume
, NULL
);
4454 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4456 IMFAudioStreamVolume_Release(stream_volume
);
4458 hr
= MFGetService((IUnknown
*)sink
, &MR_AUDIO_POLICY_SERVICE
, &IID_IMFAudioPolicy
, (void **)&unk
);
4459 ok(hr
== S_OK
, "Failed to get interface, hr %#lx.\n", hr
);
4460 IUnknown_Release(unk
);
4463 EXPECT_REF(present_clock
, 2);
4464 hr
= IMFMediaSink_Shutdown(sink
);
4465 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4466 EXPECT_REF(present_clock
, 1);
4468 hr
= IMFMediaSink_Shutdown(sink
);
4469 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4471 hr
= IMFMediaSink_AddStreamSink(sink
, 123, NULL
, &stream_sink
);
4472 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4474 hr
= IMFMediaSink_RemoveStreamSink(sink
, 0);
4475 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4477 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
4478 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4480 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
4481 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4483 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4484 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4486 hr
= IMFMediaSink_SetPresentationClock(sink
, NULL
);
4487 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4489 hr
= IMFMediaSink_SetPresentationClock(sink
, present_clock
);
4490 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4492 hr
= IMFMediaSink_GetPresentationClock(sink
, NULL
);
4493 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4495 hr
= IMFMediaSink_GetPresentationClock(sink
, &present_clock2
);
4496 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4498 check_sar_rate_support(sink
);
4500 IMFMediaSink_Release(sink
);
4503 hr
= MFCreateAudioRendererActivate(&activate
);
4504 ok(hr
== S_OK
, "Failed to create activation object, hr %#lx.\n", hr
);
4506 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4507 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4509 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4510 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4511 ok(sink
== sink2
, "Unexpected instance.\n");
4512 IMFMediaSink_Release(sink2
);
4514 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4515 ok(hr
== S_OK
, "Failed to get sink flags, hr %#lx.\n", hr
);
4517 hr
= IMFActivate_ShutdownObject(activate
);
4518 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4520 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4521 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4523 IMFMediaSink_Release(sink
);
4525 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4526 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4528 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4530 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4532 IMFMediaSink_Release(sink
);
4534 hr
= IMFActivate_DetachObject(activate
);
4535 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4537 IMFActivate_Release(activate
);
4539 IMFPresentationClock_Release(present_clock
);
4542 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
4544 /* SAR attributes */
4545 hr
= MFCreateAttributes(&attributes
, 0);
4546 ok(hr
== S_OK
, "Failed to create attributes, hr %#lx.\n", hr
);
4549 hr
= IMFAttributes_SetUINT32(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
, eMultimedia
);
4550 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4552 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4553 ok(hr
== S_OK
, "Failed to create a sink, hr %#lx.\n", hr
);
4554 IMFMediaSink_Release(sink
);
4556 /* Invalid endpoint. */
4557 hr
= IMFAttributes_SetString(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID
, L
"endpoint");
4558 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4560 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4561 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4563 hr
= IMFAttributes_DeleteItem(attributes
, &MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE
);
4564 ok(hr
== S_OK
, "Failed to remove attribute, hr %#lx.\n", hr
);
4566 hr
= MFCreateAudioRenderer(attributes
, &sink
);
4567 ok(hr
== MF_E_NO_AUDIO_PLAYBACK_DEVICE
, "Failed to create a sink, hr %#lx.\n", hr
);
4569 IMFAttributes_Release(attributes
);
4574 static void test_evr(void)
4576 static const float supported_rates
[] =
4578 0.0f
, 1.0f
, -20.0f
, 20.0f
, 1000.0f
, -1000.0f
,
4580 IMFVideoSampleAllocatorCallback
*allocator_callback
;
4581 IMFStreamSink
*stream_sink
, *stream_sink2
;
4582 IMFVideoDisplayControl
*display_control
;
4583 IMFMediaType
*media_type
, *media_type2
;
4584 IMFPresentationTimeSource
*time_source
;
4585 IMFVideoSampleAllocator
*allocator
;
4586 IMFMediaTypeHandler
*type_handler
;
4587 IMFVideoRenderer
*video_renderer
;
4588 IMFPresentationClock
*clock
;
4589 IMFMediaSink
*sink
, *sink2
;
4590 IMFAttributes
*attributes
;
4591 UINT32 attr_count
, value
;
4592 IMFActivate
*activate
;
4593 HWND window
, window2
;
4605 hr
= MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
4606 ok(hr
== S_OK
, "Startup failure, hr %#lx.\n", hr
);
4608 hr
= MFCreateVideoRenderer(&IID_IMFVideoRenderer
, (void **)&video_renderer
);
4609 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4611 hr
= IMFVideoRenderer_InitializeRenderer(video_renderer
, NULL
, NULL
);
4612 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4614 IMFVideoRenderer_Release(video_renderer
);
4616 hr
= MFCreateVideoRendererActivate(NULL
, NULL
);
4617 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4620 window
= create_window();
4621 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4622 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4624 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4625 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4626 ok(UlongToHandle(window3
) == window
, "Unexpected value.\n");
4628 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4629 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4631 check_interface(sink
, &IID_IMFMediaSinkPreroll
, TRUE
);
4632 check_interface(sink
, &IID_IMFVideoRenderer
, TRUE
);
4633 check_interface(sink
, &IID_IMFMediaEventGenerator
, TRUE
);
4634 check_interface(sink
, &IID_IMFClockStateSink
, TRUE
);
4635 check_interface(sink
, &IID_IMFGetService
, TRUE
);
4636 check_interface(sink
, &IID_IMFQualityAdvise
, TRUE
);
4637 check_interface(sink
, &IID_IMFRateSupport
, TRUE
);
4638 check_interface(sink
, &IID_IMFRateControl
, FALSE
);
4639 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
4640 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
4641 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
4642 check_service_interface(sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
4643 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
4644 check_service_interface(sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
4645 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, FALSE
);
4646 check_service_interface(sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
4647 check_service_interface(sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4649 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
,
4650 (void **)&display_control
);
4651 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4654 hr
= IMFVideoDisplayControl_GetVideoWindow(display_control
, &window2
);
4655 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4656 ok(window2
== window
, "Unexpected window %p.\n", window2
);
4658 IMFVideoDisplayControl_Release(display_control
);
4659 IMFMediaSink_Release(sink
);
4660 IMFActivate_Release(activate
);
4661 DestroyWindow(window
);
4663 hr
= MFCreateVideoRendererActivate(NULL
, &activate
);
4664 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4666 hr
= IMFActivate_GetCount(activate
, &attr_count
);
4667 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
4668 ok(attr_count
== 1, "Unexpected count %u.\n", attr_count
);
4670 hr
= IMFActivate_GetUINT64(activate
, &MF_ACTIVATE_VIDEO_WINDOW
, &window3
);
4671 ok(hr
== S_OK
, "Failed to get attribute, hr %#lx.\n", hr
);
4672 ok(!window3
, "Unexpected value.\n");
4674 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4675 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4677 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFAttributes
, (void **)&attributes
);
4678 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4679 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFMediaSink
, (void **)&unk
);
4680 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4681 IUnknown_Release(unk
);
4682 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4683 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4684 ok(!!attr_count
, "Unexpected count %u.\n", attr_count
);
4685 /* Rendering preferences are not immediately propagated to the presenter. */
4686 hr
= IMFAttributes_SetUINT32(attributes
, &EVRConfig_ForceBob
, 1);
4687 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4688 hr
= MFGetService((IUnknown
*)sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, (void **)&display_control
);
4689 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4690 hr
= IMFVideoDisplayControl_GetRenderingPrefs(display_control
, &flags
);
4691 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4692 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
4693 IMFVideoDisplayControl_Release(display_control
);
4694 IMFAttributes_Release(attributes
);
4696 /* Primary stream type handler. */
4697 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4698 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4700 hr
= IMFStreamSink_QueryInterface(stream_sink
, &IID_IMFAttributes
, (void **)&attributes
);
4701 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4702 hr
= IMFAttributes_GetCount(attributes
, &attr_count
);
4703 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4704 ok(attr_count
== 2, "Unexpected count %u.\n", attr_count
);
4706 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_REQUIRED_SAMPLE_COUNT
, &value
);
4707 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4708 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4710 hr
= IMFAttributes_GetUINT32(attributes
, &MF_SA_D3D_AWARE
, &value
);
4711 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4712 ok(value
== 1, "Unexpected attribute value %u.\n", value
);
4714 hr
= IMFAttributes_QueryInterface(attributes
, &IID_IMFStreamSink
, (void **)&unk
);
4715 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4716 IUnknown_Release(unk
);
4717 IMFAttributes_Release(attributes
);
4719 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
4720 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4722 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, NULL
);
4723 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4725 hr
= IMFMediaTypeHandler_GetMajorType(type_handler
, &guid
);
4726 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4727 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected type %s.\n", wine_dbgstr_guid(&guid
));
4729 /* Supported types are not advertised. */
4730 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, NULL
);
4731 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4734 hr
= IMFMediaTypeHandler_GetMediaTypeCount(type_handler
, &count
);
4735 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4736 ok(!count
, "Unexpected count %lu.\n", count
);
4738 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, NULL
);
4739 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4741 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler
, 0, &media_type
);
4742 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4744 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, NULL
);
4745 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4747 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type
);
4748 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4750 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, NULL
);
4751 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4753 hr
= MFCreateMediaType(&media_type
);
4754 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4756 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4757 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4759 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4760 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4762 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)640 << 32 | 480);
4763 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4765 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, NULL
, NULL
);
4766 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4768 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4769 ok(hr
== MF_E_INVALIDMEDIATYPE
, "Unexpected hr %#lx.\n", hr
);
4771 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
4772 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4774 media_type2
= (void *)0x1;
4775 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(type_handler
, media_type
, &media_type2
);
4776 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4777 ok(!media_type2
, "Unexpected media type %p.\n", media_type2
);
4779 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
4780 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4782 hr
= IMFMediaTypeHandler_GetCurrentMediaType(type_handler
, &media_type2
);
4783 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4784 hr
= IMFMediaType_QueryInterface(media_type2
, &IID_IMFVideoMediaType
, (void **)&unk
);
4785 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4786 IUnknown_Release(unk
);
4787 IMFMediaType_Release(media_type2
);
4789 IMFMediaType_Release(media_type
);
4791 IMFMediaTypeHandler_Release(type_handler
);
4793 /* Stream uses an allocator. */
4794 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
, TRUE
);
4795 check_service_interface(stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IDirect3DDeviceManager9
, TRUE
);
4797 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoProcessor
, TRUE
);
4798 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerBitmap
, TRUE
);
4799 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl
, TRUE
);
4800 check_service_interface(stream_sink
, &MR_VIDEO_MIXER_SERVICE
, &IID_IMFVideoMixerControl2
, TRUE
);
4801 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoDisplayControl
, TRUE
);
4802 check_service_interface(stream_sink
, &MR_VIDEO_RENDER_SERVICE
, &IID_IMFVideoPositionMapper
, TRUE
);
4803 check_service_interface(stream_sink
, &MF_RATE_CONTROL_SERVICE
, &IID_IMFRateSupport
, TRUE
);
4805 hr
= MFGetService((IUnknown
*)stream_sink
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4806 (void **)&allocator
);
4807 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4809 hr
= IMFVideoSampleAllocator_QueryInterface(allocator
, &IID_IMFVideoSampleAllocatorCallback
, (void **)&allocator_callback
);
4810 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4813 hr
= IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_callback
, &sample_count
);
4814 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4815 ok(!sample_count
, "Unexpected sample count %ld.\n", sample_count
);
4817 hr
= IMFVideoSampleAllocator_AllocateSample(allocator
, &sample
);
4818 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
4820 IMFVideoSampleAllocatorCallback_Release(allocator_callback
);
4821 IMFVideoSampleAllocator_Release(allocator
);
4823 /* Same test for a substream. */
4824 hr
= IMFMediaSink_AddStreamSink(sink
, 1, NULL
, &stream_sink2
);
4825 ok(hr
== S_OK
|| broken(hr
== E_INVALIDARG
), "Unexpected hr %#lx.\n", hr
);
4829 hr
= MFGetService((IUnknown
*)stream_sink2
, &MR_VIDEO_ACCELERATION_SERVICE
, &IID_IMFVideoSampleAllocator
,
4830 (void **)&allocator
);
4831 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4832 IMFVideoSampleAllocator_Release(allocator
);
4834 hr
= IMFMediaSink_RemoveStreamSink(sink
, 1);
4835 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4837 IMFStreamSink_Release(stream_sink2
);
4840 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4841 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4842 ok(flags
== (MEDIASINK_CAN_PREROLL
| MEDIASINK_CLOCK_REQUIRED
), "Unexpected flags %#lx.\n", flags
);
4844 hr
= IMFActivate_ShutdownObject(activate
);
4845 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4847 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4848 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4850 /* Activate again. */
4851 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4852 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4854 ok(sink
== sink2
, "Unexpected instance.\n");
4855 IMFMediaSink_Release(sink2
);
4857 hr
= IMFActivate_DetachObject(activate
);
4858 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
4860 hr
= IMFMediaSink_GetCharacteristics(sink
, &flags
);
4861 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
4863 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink2
);
4864 ok(hr
== S_OK
, "Failed to activate, hr %#lx.\n", hr
);
4866 hr
= IMFActivate_ShutdownObject(activate
);
4867 ok(hr
== S_OK
, "Failed to shut down, hr %#lx.\n", hr
);
4869 IMFMediaSink_Release(sink2
);
4870 IMFMediaSink_Release(sink
);
4872 IMFActivate_Release(activate
);
4875 window
= create_window();
4877 hr
= MFCreateVideoRendererActivate(window
, &activate
);
4878 ok(hr
== S_OK
, "Failed to create activate object, hr %#lx.\n", hr
);
4880 hr
= IMFActivate_ActivateObject(activate
, &IID_IMFMediaSink
, (void **)&sink
);
4881 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4883 hr
= MFCreateSystemTimeSource(&time_source
);
4884 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4886 hr
= MFCreatePresentationClock(&clock
);
4887 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4889 hr
= IMFPresentationClock_SetTimeSource(clock
, time_source
);
4890 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4891 IMFPresentationTimeSource_Release(time_source
);
4893 hr
= IMFMediaSink_SetPresentationClock(sink
, clock
);
4894 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4896 hr
= IMFMediaSink_QueryInterface(sink
, &IID_IMFRateSupport
, (void **)&rs
);
4897 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4900 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4901 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4902 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4905 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
4906 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4907 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4910 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4911 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4912 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4915 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4916 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4917 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4919 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
4920 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4922 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, FALSE
, &rate
);
4923 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4925 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4926 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4928 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4929 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4931 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4932 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4934 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
4936 rate
= supported_rates
[i
] + 1.0f
;
4937 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
4938 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4939 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4941 rate
= supported_rates
[i
] + 1.0f
;
4942 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
4943 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4944 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
4946 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
4947 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4949 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
4950 ok(hr
== MF_E_INVALIDREQUEST
, "Unexpected hr %#lx.\n", hr
);
4953 /* Configuring stream type make rate support work. */
4954 hr
= IMFMediaSink_GetStreamSinkById(sink
, 0, &stream_sink
);
4955 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4956 hr
= IMFStreamSink_GetMediaTypeHandler(stream_sink
, &type_handler
);
4957 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4958 hr
= MFCreateMediaType(&media_type
);
4959 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4960 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4961 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4962 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4963 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4964 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)64 << 32 | 64);
4965 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4966 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_ALL_SAMPLES_INDEPENDENT
, TRUE
);
4967 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4968 hr
= IMFMediaTypeHandler_SetCurrentMediaType(type_handler
, media_type
);
4969 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
4972 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4973 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4974 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4977 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4978 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4979 ok(rate
== 0.0f
, "Unexpected rate %f.\n", rate
);
4982 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, TRUE
, &rate
);
4983 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4984 ok(rate
== FLT_MAX
, "Unexpected rate %f.\n", rate
);
4987 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, &rate
);
4988 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4989 ok(rate
== -FLT_MAX
, "Unexpected rate %f.\n", rate
);
4991 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4992 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4994 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_REVERSE
, TRUE
, NULL
);
4995 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
4997 for (i
= 0; i
< ARRAY_SIZE(supported_rates
); ++i
)
4999 rate
= supported_rates
[i
] + 1.0f
;
5000 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], &rate
);
5001 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5002 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5004 rate
= supported_rates
[i
] + 1.0f
;
5005 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], &rate
);
5006 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5007 ok(rate
== supported_rates
[i
], "Unexpected rate %f.\n", rate
);
5009 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, supported_rates
[i
], NULL
);
5010 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5012 hr
= IMFRateSupport_IsRateSupported(rs
, FALSE
, supported_rates
[i
], NULL
);
5013 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5016 IMFMediaTypeHandler_Release(type_handler
);
5017 IMFMediaType_Release(media_type
);
5018 IMFStreamSink_Release(stream_sink
);
5020 hr
= IMFMediaSink_Shutdown(sink
);
5021 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5023 hr
= IMFMediaSink_GetStreamSinkCount(sink
, NULL
);
5024 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5026 hr
= IMFMediaSink_GetStreamSinkCount(sink
, &count
);
5027 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5029 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5030 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5032 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, &rate
);
5033 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5035 hr
= IMFRateSupport_GetSlowestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
5036 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5038 hr
= IMFRateSupport_GetFastestRate(rs
, MFRATE_FORWARD
, FALSE
, NULL
);
5039 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5041 hr
= IMFRateSupport_IsRateSupported(rs
, TRUE
, 1.0f
, &rate
);
5042 ok(hr
== MF_E_SHUTDOWN
, "Unexpected hr %#lx.\n", hr
);
5044 IMFPresentationClock_Release(clock
);
5046 IMFActivate_Release(activate
);
5047 DestroyWindow(window
);
5050 ok(hr
== S_OK
, "Shutdown failure, hr %#lx.\n", hr
);
5053 static void test_MFCreateSimpleTypeHandler(void)
5055 IMFMediaType
*media_type
, *media_type2
, *media_type3
;
5056 IMFMediaTypeHandler
*handler
;
5061 hr
= MFCreateSimpleTypeHandler(&handler
);
5062 ok(hr
== S_OK
, "Failed to create object, hr %#lx.\n", hr
);
5064 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, NULL
);
5065 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5067 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
5068 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
5071 hr
= IMFMediaTypeHandler_GetMediaTypeCount(handler
, &count
);
5072 ok(hr
== S_OK
, "Failed to get type count, hr %#lx.\n", hr
);
5073 ok(count
== 1, "Unexpected count %lu.\n", count
);
5075 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, NULL
);
5076 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5078 media_type
= (void *)0xdeadbeef;
5079 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
5080 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5081 ok(!media_type
, "Unexpected pointer.\n");
5083 hr
= MFCreateMediaType(&media_type
);
5084 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5086 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
5087 ok(hr
== MF_E_UNEXPECTED
, "Unexpected hr %#lx.\n", hr
);
5089 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, media_type
);
5090 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5092 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 0, &media_type2
);
5093 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5094 ok(media_type2
== media_type
, "Unexpected type.\n");
5095 IMFMediaType_Release(media_type2
);
5097 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, NULL
, NULL
);
5098 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5100 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, NULL
);
5101 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5103 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type
, &media_type2
);
5104 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5106 hr
= IMFMediaTypeHandler_GetMediaTypeByIndex(handler
, 1, &media_type2
);
5107 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5109 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type2
);
5110 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5111 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5112 IMFMediaType_Release(media_type2
);
5114 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5115 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
5117 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5118 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5120 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5121 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5122 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
5124 hr
= MFCreateMediaType(&media_type3
);
5125 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5127 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, NULL
);
5128 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5130 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Audio
);
5131 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5133 /* Different major types. */
5134 media_type2
= (void *)0xdeadbeef;
5135 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5136 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5137 ok(!media_type2
, "Unexpected pointer.\n");
5139 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5140 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5142 media_type2
= (void *)0xdeadbeef;
5143 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5144 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5145 ok(!media_type2
, "Unexpected pointer.\n");
5147 /* Handler missing subtype. */
5148 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
5149 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5151 media_type2
= (void *)0xdeadbeef;
5152 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5153 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5154 ok(!media_type2
, "Unexpected pointer.\n");
5156 /* Different subtypes. */
5157 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
5158 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5160 media_type2
= (void *)0xdeadbeef;
5161 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5162 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5163 ok(!media_type2
, "Unexpected pointer.\n");
5165 /* Same major/subtype. */
5166 hr
= IMFMediaType_SetGUID(media_type3
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB24
);
5167 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5169 media_type2
= (void *)0xdeadbeef;
5170 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5171 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5172 ok(!media_type2
, "Unexpected pointer.\n");
5174 /* Set one more attribute. */
5175 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)4 << 32 | 4);
5176 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5178 media_type2
= (void *)0xdeadbeef;
5179 hr
= IMFMediaTypeHandler_IsMediaTypeSupported(handler
, media_type3
, &media_type2
);
5180 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5181 ok(!media_type2
, "Unexpected pointer.\n");
5183 IMFMediaType_Release(media_type3
);
5184 IMFMediaType_Release(media_type
);
5186 hr
= IMFMediaTypeHandler_SetCurrentMediaType(handler
, NULL
);
5187 ok(hr
== S_OK
, "Failed to set current type, hr %#lx.\n", hr
);
5189 media_type
= (void *)0xdeadbeef;
5190 hr
= IMFMediaTypeHandler_GetCurrentMediaType(handler
, &media_type
);
5191 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5192 ok(!media_type
, "Unexpected pointer.\n");
5194 hr
= IMFMediaTypeHandler_GetMajorType(handler
, &guid
);
5195 ok(hr
== MF_E_NOT_INITIALIZED
, "Unexpected hr %#lx.\n", hr
);
5197 IMFMediaTypeHandler_Release(handler
);
5200 static void test_MFGetSupportedMimeTypes(void)
5205 hr
= MFGetSupportedMimeTypes(NULL
);
5206 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5208 value
.vt
= VT_EMPTY
;
5209 hr
= MFGetSupportedMimeTypes(&value
);
5210 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5211 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5213 PropVariantClear(&value
);
5216 static void test_MFGetSupportedSchemes(void)
5221 hr
= MFGetSupportedSchemes(NULL
);
5222 ok(hr
== E_POINTER
, "Unexpected hr %#lx.\n", hr
);
5224 value
.vt
= VT_EMPTY
;
5225 hr
= MFGetSupportedSchemes(&value
);
5226 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5227 ok(value
.vt
== (VT_VECTOR
| VT_LPWSTR
), "Unexpected value type %#x.\n", value
.vt
);
5229 PropVariantClear(&value
);
5232 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
5238 hr
= IMFMediaType_GetMajorType(type
, &major
);
5239 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5241 hr
= IMFMediaType_GetCount(type
, &count
);
5242 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
5243 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5245 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
5248 static void test_sample_copier(void)
5250 IMFAttributes
*attributes
, *attributes2
;
5251 DWORD in_min
, in_max
, out_min
, out_max
;
5252 IMFMediaType
*mediatype
, *mediatype2
;
5253 MFT_OUTPUT_STREAM_INFO output_info
;
5254 IMFSample
*sample
, *client_sample
;
5255 MFT_INPUT_STREAM_INFO input_info
;
5256 DWORD input_count
, output_count
;
5257 MFT_OUTPUT_DATA_BUFFER buffer
;
5258 IMFMediaBuffer
*media_buffer
;
5259 IMFTransform
*copier
;
5260 DWORD flags
, status
;
5261 UINT32 value
, count
;
5264 if (!pMFCreateSampleCopierMFT
)
5266 win_skip("MFCreateSampleCopierMFT() is not available.\n");
5270 hr
= pMFCreateSampleCopierMFT(&copier
);
5271 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5273 hr
= IMFTransform_GetAttributes(copier
, &attributes
);
5274 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5275 hr
= IMFTransform_GetAttributes(copier
, &attributes2
);
5276 ok(hr
== S_OK
, "Failed to get transform attributes, hr %#lx.\n", hr
);
5277 ok(attributes
== attributes2
, "Unexpected instance.\n");
5278 IMFAttributes_Release(attributes2
);
5279 hr
= IMFAttributes_GetCount(attributes
, &count
);
5280 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5281 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
5282 hr
= IMFAttributes_GetUINT32(attributes
, &MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, &value
);
5283 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5284 ok(!!value
, "Unexpected value %u.\n", value
);
5285 IMFAttributes_Release(attributes
);
5287 hr
= IMFTransform_GetInputStreamAttributes(copier
, 0, &attributes
);
5288 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5290 hr
= IMFTransform_GetInputStreamAttributes(copier
, 1, &attributes
);
5291 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5293 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 0, &attributes
);
5294 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5296 hr
= IMFTransform_GetOutputStreamAttributes(copier
, 1, &attributes
);
5297 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5299 hr
= IMFTransform_SetOutputBounds(copier
, 0, 0);
5300 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5302 /* No dynamic streams. */
5303 input_count
= output_count
= 0;
5304 hr
= IMFTransform_GetStreamCount(copier
, &input_count
, &output_count
);
5305 ok(hr
== S_OK
, "Failed to get stream count, hr %#lx.\n", hr
);
5306 ok(input_count
== 1 && output_count
== 1, "Unexpected streams count.\n");
5308 hr
= IMFTransform_GetStreamLimits(copier
, &in_min
, &in_max
, &out_min
, &out_max
);
5309 ok(hr
== S_OK
, "Failed to get stream limits, hr %#lx.\n", hr
);
5310 ok(in_min
== in_max
&& in_min
== 1 && out_min
== out_max
&& out_min
== 1, "Unexpected stream limits.\n");
5312 hr
= IMFTransform_GetStreamIDs(copier
, 1, &input_count
, 1, &output_count
);
5313 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5315 hr
= IMFTransform_DeleteInputStream(copier
, 0);
5316 ok(hr
== E_NOTIMPL
, "Unexpected hr %#lx.\n", hr
);
5318 /* Available types. */
5319 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
5320 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5321 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5322 IMFMediaType_Release(mediatype
);
5324 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
5325 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5326 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
5327 IMFMediaType_Release(mediatype
);
5329 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
5330 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5332 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
5333 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5335 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
5336 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5338 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
5339 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5341 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype
);
5342 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5344 hr
= IMFTransform_GetInputCurrentType(copier
, 1, &mediatype
);
5345 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5347 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype
);
5348 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5350 hr
= IMFTransform_GetOutputCurrentType(copier
, 1, &mediatype
);
5351 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
5353 hr
= MFCreateSample(&sample
);
5354 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5356 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5357 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5359 hr
= MFCreateMediaType(&mediatype
);
5360 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5362 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5363 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
5365 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5366 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5368 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
5369 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5371 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5372 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5374 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5375 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5376 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5377 ok(!output_info
.cbSize
, "Unexpected size %lu.\n", output_info
.cbSize
);
5378 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5380 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5381 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5383 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5384 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5385 ok(!input_info
.cbSize
, "Unexpected size %lu.\n", input_info
.cbSize
);
5386 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5387 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5389 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5390 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5392 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5393 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5394 ok(!output_info
.dwFlags
, "Unexpected flags %#lx.\n", output_info
.dwFlags
);
5395 ok(output_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", output_info
.cbSize
);
5396 ok(!output_info
.cbAlignment
, "Unexpected alignment %lu.\n", output_info
.cbAlignment
);
5398 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5399 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5400 IMFMediaType_Release(mediatype2
);
5402 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5403 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5405 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5406 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5408 /* Setting input type resets output type. */
5409 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5410 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5411 IMFMediaType_Release(mediatype2
);
5413 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5414 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5416 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
5417 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5419 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
5420 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5421 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
5422 IMFMediaType_Release(mediatype2
);
5424 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &input_info
);
5425 ok(hr
== S_OK
, "Failed to get stream info, hr %#lx.\n", hr
);
5426 ok(!input_info
.hnsMaxLatency
, "Unexpected latency %s.\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
5427 ok(!input_info
.dwFlags
, "Unexpected flags %#lx.\n", input_info
.dwFlags
);
5428 ok(input_info
.cbSize
== 16 * 16, "Unexpected size %lu.\n", input_info
.cbSize
);
5429 ok(!input_info
.cbMaxLookahead
, "Unexpected lookahead size %lu.\n", input_info
.cbMaxLookahead
);
5430 ok(!input_info
.cbAlignment
, "Unexpected alignment %lu.\n", input_info
.cbAlignment
);
5432 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
5433 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5434 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
5435 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5436 IMFMediaType_Release(mediatype2
);
5438 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5439 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5440 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
5442 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
5443 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5444 IMFMediaType_Release(mediatype2
);
5446 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5447 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5449 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5450 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
5452 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5453 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5454 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5456 /* Pushing samples. */
5457 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5458 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5460 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
5461 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5462 IMFMediaBuffer_Release(media_buffer
);
5464 EXPECT_REF(sample
, 1);
5465 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5466 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5467 EXPECT_REF(sample
, 2);
5469 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
5470 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5471 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
5473 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
5474 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
5475 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
5477 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5478 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
5480 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5481 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5483 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
5484 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5486 hr
= MFCreateSample(&client_sample
);
5487 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5489 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
5490 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5491 IMFMediaBuffer_Release(media_buffer
);
5494 memset(&buffer
, 0, sizeof(buffer
));
5495 buffer
.pSample
= client_sample
;
5496 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5497 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5498 EXPECT_REF(sample
, 1);
5500 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5501 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
5504 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
5505 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5506 EXPECT_REF(sample
, 2);
5508 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
5509 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
5510 EXPECT_REF(sample
, 1);
5512 IMFSample_Release(sample
);
5513 IMFSample_Release(client_sample
);
5515 IMFMediaType_Release(mediatype
);
5516 IMFTransform_Release(copier
);
5519 struct sample_metadata
5526 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
5527 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
5529 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
5530 IMFSample
*input_sample
, *output_sample
;
5531 MFT_OUTPUT_DATA_BUFFER buffer
;
5532 DWORD flags
, status
;
5536 hr
= MFCreateSample(&input_sample
);
5537 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5541 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
5542 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5544 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
5545 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5547 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
5548 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5551 hr
= MFCreateSample(&output_sample
);
5552 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5554 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
5555 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5557 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
5558 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5560 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
5561 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5563 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
5564 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5566 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
5567 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5569 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
5570 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
5573 memset(&buffer
, 0, sizeof(buffer
));
5574 buffer
.pSample
= output_sample
;
5575 hr
= IMFTransform_ProcessOutput(copier
, 0, 1, &buffer
, &status
);
5576 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
5578 if (!md
) md
= &zero_md
;
5580 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
5581 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5582 ok(md
->flags
== flags
, "Unexpected flags.\n");
5583 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
5584 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5585 ok(md
->time
== time
, "Unexpected time.\n");
5586 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
5587 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5588 ok(md
->duration
== time
, "Unexpected duration.\n");
5590 IMFSample_Release(input_sample
);
5591 IMFSample_Release(output_sample
);
5594 static void test_sample_copier_output_processing(void)
5596 IMFMediaBuffer
*input_buffer
, *output_buffer
;
5597 MFT_OUTPUT_STREAM_INFO output_info
;
5598 struct sample_metadata md
;
5599 IMFMediaType
*mediatype
;
5600 IMFTransform
*copier
;
5605 if (!pMFCreateSampleCopierMFT
)
5608 hr
= pMFCreateSampleCopierMFT(&copier
);
5609 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
5611 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
5612 hr
= MFCreateMediaType(&mediatype
);
5613 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5615 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5616 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5618 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5619 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5621 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
5622 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5624 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
5625 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5627 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
5628 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5630 /* Source and destination are linear buffers, destination is twice as large. */
5631 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
5632 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
5634 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
5635 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5637 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5638 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5639 memset(ptr
, 0xcc, max_length
);
5640 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5641 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5643 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
5644 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
5646 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
5647 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5648 memset(ptr
, 0xaa, max_length
);
5649 hr
= IMFMediaBuffer_Unlock(input_buffer
);
5650 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5651 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
5652 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5654 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
5656 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
5657 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5658 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
5660 hr
= IMFMediaBuffer_Unlock(output_buffer
);
5661 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5666 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
5668 IMFMediaBuffer_Release(input_buffer
);
5669 IMFMediaBuffer_Release(output_buffer
);
5671 IMFMediaType_Release(mediatype
);
5672 IMFTransform_Release(copier
);
5675 static void test_MFGetTopoNodeCurrentType(void)
5677 IMFMediaType
*media_type
, *media_type2
;
5678 IMFTopologyNode
*node
;
5681 if (!pMFGetTopoNodeCurrentType
)
5683 win_skip("MFGetTopoNodeCurrentType() is unsupported.\n");
5688 hr
= MFCreateTopologyNode(MF_TOPOLOGY_TEE_NODE
, &node
);
5689 ok(hr
== S_OK
, "Failed to create a node, hr %#lx.\n", hr
);
5691 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5692 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5694 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5695 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5697 hr
= MFCreateMediaType(&media_type2
);
5698 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5700 hr
= IMFMediaType_SetGUID(media_type2
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5701 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5703 /* Input type returned, if set. */
5704 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, media_type2
);
5705 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5707 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5708 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5709 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5710 IMFMediaType_Release(media_type
);
5712 hr
= IMFTopologyNode_SetInputPrefType(node
, 0, NULL
);
5713 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5715 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5716 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5718 /* Set second output. */
5719 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5720 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5722 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5723 ok(hr
== E_FAIL
, "Unexpected hr %#lx.\n", hr
);
5725 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, NULL
);
5726 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5728 /* Set first output. */
5729 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, media_type2
);
5730 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5732 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5733 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5734 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5735 IMFMediaType_Release(media_type
);
5737 hr
= IMFTopologyNode_SetOutputPrefType(node
, 0, NULL
);
5738 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5740 /* Set primary output. */
5741 hr
= IMFTopologyNode_SetOutputPrefType(node
, 1, media_type2
);
5742 ok(hr
== S_OK
, "Failed to set media type, hr %#lx.\n", hr
);
5744 hr
= IMFTopologyNode_SetUINT32(node
, &MF_TOPONODE_PRIMARYOUTPUT
, 1);
5745 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5747 hr
= pMFGetTopoNodeCurrentType(node
, 0, FALSE
, &media_type
);
5748 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5749 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5750 IMFMediaType_Release(media_type
);
5752 hr
= pMFGetTopoNodeCurrentType(node
, 0, TRUE
, &media_type
);
5753 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5754 ok(media_type
== media_type2
, "Unexpected pointer.\n");
5755 IMFMediaType_Release(media_type
);
5757 IMFTopologyNode_Release(node
);
5758 IMFMediaType_Release(media_type2
);
5761 static void init_functions(void)
5763 HMODULE mod
= GetModuleHandleA("mf.dll");
5765 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
5766 X(MFCreateSampleCopierMFT
);
5767 X(MFGetTopoNodeCurrentType
);
5771 static void test_MFRequireProtectedEnvironment(void)
5773 IMFPresentationDescriptor
*pd
;
5774 IMFMediaType
*mediatype
;
5775 IMFStreamDescriptor
*sd
;
5778 hr
= MFCreateMediaType(&mediatype
);
5779 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5781 hr
= MFCreateStreamDescriptor(0, 1, &mediatype
, &sd
);
5782 ok(hr
== S_OK
, "Failed to create stream descriptor, hr %#lx.\n", hr
);
5784 hr
= MFCreatePresentationDescriptor(1, &sd
, &pd
);
5785 ok(hr
== S_OK
, "Failed to create presentation descriptor, hr %#lx.\n", hr
);
5787 hr
= IMFPresentationDescriptor_SelectStream(pd
, 0);
5788 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5790 hr
= MFRequireProtectedEnvironment(pd
);
5791 ok(hr
== S_FALSE
, "Unexpected hr %#lx.\n", hr
);
5793 hr
= IMFStreamDescriptor_SetUINT32(sd
, &MF_SD_PROTECTED
, 1);
5794 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5796 hr
= MFRequireProtectedEnvironment(pd
);
5797 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5799 hr
= IMFPresentationDescriptor_DeselectStream(pd
, 0);
5800 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5802 hr
= MFRequireProtectedEnvironment(pd
);
5803 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5805 IMFMediaType_Release(mediatype
);
5806 IMFStreamDescriptor_Release(sd
);
5807 IMFPresentationDescriptor_Release(pd
);
5810 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
5812 IMFMediaBuffer
*media_buffer
;
5819 hr
= MFCreateSample(&sample
);
5820 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
5821 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
5822 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
5823 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5824 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5825 ok(length
== 0, "got length %lu\n", length
);
5826 if (!data
) memset(buffer
, 0xcd, size
);
5827 else memcpy(buffer
, data
, size
);
5828 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5829 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5830 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
5831 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
5832 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
5833 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
5834 ret
= IMFMediaBuffer_Release(media_buffer
);
5835 ok(ret
== 1, "Release returned %lu\n", ret
);
5840 #define check_sample(a, b, c) check_sample_(__LINE__, a, b, c)
5841 static void check_sample_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
)
5843 IMFMediaBuffer
*media_buffer
;
5849 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
5850 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
5851 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5852 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5853 ok_(__FILE__
, line
)(!memcmp(expect_buf
, buffer
, length
), "unexpected buffer data\n");
5854 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
5855 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5856 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5857 ret
= IMFMediaBuffer_Release(media_buffer
);
5858 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
5861 #define check_sample_rgb32(a, b, c) check_sample_rgb32_(__LINE__, a, b, c)
5862 static void check_sample_rgb32_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
)
5864 DWORD i
, length
, diff
= 0, max_diff
;
5865 IMFMediaBuffer
*media_buffer
;
5870 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
5871 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
5872 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5873 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5875 /* check that buffer values are "close" enough, there's some pretty big
5876 * differences with the color converter between ffmpeg and native.
5878 for (i
= 0; i
< length
; i
++)
5880 if (i
% 4 == 3) continue; /* ignore alpha diff */
5881 diff
+= abs((int)expect_buf
[i
] - (int)buffer
[i
]);
5883 max_diff
= length
* 3 * 256;
5884 ok_(__FILE__
, line
)(diff
* 100 / max_diff
== 0, "unexpected buffer data\n");
5886 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
5887 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5888 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5889 ret
= IMFMediaBuffer_Release(media_buffer
);
5890 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
5893 #define check_sample_pcm16(a, b, c, d) check_sample_pcm16_(__LINE__, a, b, c, d)
5894 static void check_sample_pcm16_(int line
, IMFSample
*sample
, const BYTE
*expect_buf
, HANDLE output_file
, BOOL todo
)
5896 IMFMediaBuffer
*media_buffer
;
5902 hr
= IMFSample_ConvertToContiguousBuffer(sample
, &media_buffer
);
5903 ok_(__FILE__
, line
)(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
5904 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
5905 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
5907 /* check that buffer values are close enough, there's some differences in
5908 * the output of audio DSP between 32bit and 64bit implementation
5910 for (i
= 0; i
< length
; i
+= 2)
5912 DWORD expect
= *(INT16
*)(expect_buf
+ i
), value
= *(INT16
*)(buffer
+ i
);
5913 if (expect
- value
+ 512 > 1024) break;
5917 ok_(__FILE__
, line
)(i
== length
, "unexpected buffer data\n");
5919 if (output_file
) WriteFile(output_file
, buffer
, length
, &length
, NULL
);
5920 hr
= IMFMediaBuffer_Unlock(media_buffer
);
5921 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
5922 ret
= IMFMediaBuffer_Release(media_buffer
);
5923 ok_(__FILE__
, line
)(ret
== 1, "Release returned %lu\n", ret
);
5926 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
5927 static const ULONG wmaenc_block_size
= 1487;
5928 static const ULONG wmadec_block_size
= 0x2000;
5930 static void test_wma_encoder(void)
5932 const GUID transform_inputs
[] =
5935 MFAudioFormat_Float
,
5937 const GUID transform_outputs
[] =
5939 MFAudioFormat_WMAudioV8
,
5940 MFAudioFormat_WMAudioV9
,
5941 MFAudioFormat_WMAudio_Lossless
,
5943 const GUID dmo_inputs
[] =
5947 const GUID dmo_outputs
[] =
5949 MEDIASUBTYPE_WMAUDIO2
,
5950 MEDIASUBTYPE_WMAUDIO3
,
5951 MEDIASUBTYPE_WMAUDIO_LOSSLESS
,
5954 static const struct attribute_desc input_type_desc
[] =
5956 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5957 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5958 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
5959 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5960 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5961 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
5962 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
5965 const struct attribute_desc output_type_desc
[] =
5967 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5968 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
5969 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5970 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5971 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
5972 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
5973 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
5977 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
5978 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
5979 ULONG audio_data_len
, wmaenc_data_len
;
5980 const BYTE
*audio_data
, *wmaenc_data
;
5981 MFT_OUTPUT_STREAM_INFO output_info
;
5982 MFT_INPUT_STREAM_INFO input_info
;
5983 MFT_OUTPUT_DATA_BUFFER output
;
5984 WCHAR output_path
[MAX_PATH
];
5985 IMFMediaType
*media_type
;
5986 IMFTransform
*transform
;
5987 DWORD status
, length
;
5995 hr
= CoInitialize(NULL
);
5996 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5998 if (!create_transform(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, L
"WMAudio Encoder MFT", &MFMediaType_Audio
,
5999 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6000 &transform
, &CLSID_CWMAEncMediaObject
, &class_id
))
6003 check_dmo(&class_id
, L
"WMAudio Encoder DMO", &MEDIATYPE_Audio
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
6004 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
6006 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6007 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6008 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6009 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
6011 hr
= MFCreateMediaType(&media_type
);
6012 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6013 init_media_type(media_type
, input_type_desc
, -1);
6014 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6015 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6016 init_media_type(media_type
, output_type_desc
, -1);
6017 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6018 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6019 ret
= IMFMediaType_Release(media_type
);
6020 ok(ret
== 0, "Release returned %lu\n", ret
);
6022 memset(&input_info
, 0xcd, sizeof(input_info
));
6023 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6024 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6025 ok(input_info
.hnsMaxLatency
== 19969161, "got hnsMaxLatency %s\n",
6026 wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6027 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
6028 ok(input_info
.cbSize
== 8, "got cbSize %lu\n", input_info
.cbSize
);
6029 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6030 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6032 memset(&output_info
, 0xcd, sizeof(output_info
));
6033 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6034 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6035 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6036 ok(output_info
.cbSize
== wmaenc_block_size
, "got cbSize %#lx\n", output_info
.cbSize
);
6037 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6039 resource
= FindResourceW(NULL
, L
"audiodata.bin", (const WCHAR
*)RT_RCDATA
);
6040 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6041 audio_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6042 audio_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6043 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
6045 sample
= create_sample(audio_data
, audio_data_len
);
6046 hr
= IMFSample_SetSampleTime(sample
, 0);
6047 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
6048 hr
= IMFSample_SetSampleDuration(sample
, 10000000);
6049 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
6050 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6051 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6052 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6053 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6054 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6055 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6056 IMFSample_Release(sample
);
6058 status
= 0xdeadbeef;
6059 sample
= create_sample(NULL
, output_info
.cbSize
);
6060 memset(&output
, 0, sizeof(output
));
6061 output
.pSample
= sample
;
6063 resource
= FindResourceW(NULL
, L
"wmaencdata.bin", (const WCHAR
*)RT_RCDATA
);
6064 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6065 wmaenc_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6066 wmaenc_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6067 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
6069 /* and generate a new one as well in a temporary directory */
6070 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
6071 lstrcatW(output_path
, L
"wmaencdata.bin");
6072 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
6073 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
6076 while (SUCCEEDED(hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
)))
6078 winetest_push_context("%lu", i
);
6079 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6080 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6081 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
6082 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)) /* win7 */,
6083 "got dwStatus %#lx\n", output
.dwStatus
);
6084 ok(status
== 0, "got status %#lx\n", status
);
6085 hr
= IMFSample_GetTotalLength(sample
, &length
);
6086 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6087 ok(length
== wmaenc_block_size
, "got length %lu\n", length
);
6088 ok(wmaenc_data_len
> i
* wmaenc_block_size
, "got %lu blocks\n", i
);
6089 check_sample(sample
, wmaenc_data
+ i
* wmaenc_block_size
, output_file
);
6090 winetest_pop_context();
6094 trace("created %s\n", debugstr_w(output_path
));
6095 CloseHandle(output_file
);
6097 ret
= IMFSample_Release(sample
);
6098 ok(ret
== 0, "Release returned %lu\n", ret
);
6100 status
= 0xdeadbeef;
6101 sample
= create_sample(NULL
, output_info
.cbSize
);
6102 memset(&output
, 0, sizeof(output
));
6103 output
.pSample
= sample
;
6104 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6105 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6106 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6107 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6108 ok(status
== 0, "got status %#lx\n", status
);
6109 hr
= IMFSample_GetTotalLength(sample
, &length
);
6110 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6111 ok(length
== 0, "got length %lu\n", length
);
6112 ret
= IMFSample_Release(sample
);
6113 ok(ret
== 0, "Release returned %lu\n", ret
);
6115 ret
= IMFTransform_Release(transform
);
6116 ok(ret
== 0, "Release returned %lu\n", ret
);
6122 static void test_wma_decoder(void)
6124 const GUID transform_inputs
[] =
6126 MEDIASUBTYPE_MSAUDIO1
,
6127 MFAudioFormat_WMAudioV8
,
6128 MFAudioFormat_WMAudioV9
,
6129 MFAudioFormat_WMAudio_Lossless
,
6131 const GUID transform_outputs
[] =
6134 MFAudioFormat_Float
,
6136 const GUID dmo_inputs
[] =
6138 MEDIASUBTYPE_MSAUDIO1
,
6139 MEDIASUBTYPE_WMAUDIO2
,
6140 MEDIASUBTYPE_WMAUDIO3
,
6141 MEDIASUBTYPE_WMAUDIO_LOSSLESS
,
6143 const GUID dmo_outputs
[] =
6146 MEDIASUBTYPE_IEEE_FLOAT
,
6149 static const media_type_desc expect_available_inputs
[] =
6152 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6153 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
6154 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6157 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6158 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6159 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6162 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6163 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
6164 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6167 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6168 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
6169 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6172 static const media_type_desc expect_available_outputs
[] =
6175 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6176 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6177 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6178 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6179 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6180 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
6181 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
6182 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6183 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6184 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6187 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6188 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6189 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6190 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6191 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6192 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6193 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6194 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6195 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6196 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6200 const struct attribute_desc input_type_desc
[] =
6202 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6203 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
6204 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
6205 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
6206 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6207 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6210 static const struct attribute_desc output_type_desc
[] =
6212 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6213 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6214 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6215 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6216 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6217 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6218 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6222 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
6223 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
6224 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
6225 ULONG wmadec_data_len
, wmaenc_data_len
;
6226 const BYTE
*wmadec_data
, *wmaenc_data
;
6227 MFT_OUTPUT_STREAM_INFO output_info
;
6228 MFT_OUTPUT_DATA_BUFFER outputs
[2];
6229 MFT_INPUT_STREAM_INFO input_info
;
6230 MFT_OUTPUT_DATA_BUFFER output
;
6231 DWORD status
, flags
, length
;
6232 WCHAR output_path
[MAX_PATH
];
6233 IMediaObject
*media_object
;
6234 IPropertyBag
*property_bag
;
6235 IMFMediaType
*media_type
;
6236 IMFTransform
*transform
;
6237 LONGLONG time
, duration
;
6246 hr
= CoInitialize(NULL
);
6247 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6249 if (!create_transform(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, L
"WMAudio Decoder MFT", &MFMediaType_Audio
,
6250 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6251 &transform
, &CLSID_CWMADecMediaObject
, &class_id
))
6254 check_dmo(&class_id
, L
"WMAudio Decoder DMO", &MEDIATYPE_Audio
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
6255 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
6257 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6258 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6260 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6261 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
6263 /* check default media types */
6265 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6266 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6267 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6268 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6269 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6270 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6273 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6275 winetest_push_context("in %lu", i
);
6276 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6277 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6278 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6279 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6280 ret
= IMFMediaType_Release(media_type
);
6281 ok(ret
== 0, "Release returned %lu\n", ret
);
6282 winetest_pop_context();
6285 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6287 ok(i
== 4, "%lu input media types\n", i
);
6289 /* setting output media type first doesn't work */
6291 hr
= MFCreateMediaType(&media_type
);
6292 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6293 init_media_type(media_type
, output_type_desc
, -1);
6294 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6295 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
6296 ret
= IMFMediaType_Release(media_type
);
6297 ok(ret
== 0, "Release returned %lu\n", ret
);
6299 /* check required input media type attributes */
6301 hr
= MFCreateMediaType(&media_type
);
6302 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6303 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6304 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6305 init_media_type(media_type
, input_type_desc
, 1);
6306 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6307 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6308 init_media_type(media_type
, input_type_desc
, 2);
6309 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
6311 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6312 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
6313 init_media_type(media_type
, input_type_desc
, i
+ 1);
6315 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6316 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6317 ret
= IMFMediaType_Release(media_type
);
6318 ok(ret
== 0, "Release returned %lu\n", ret
);
6320 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6321 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
6322 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6323 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6325 /* check new output media types */
6328 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6330 winetest_push_context("out %lu", i
);
6331 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6332 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6333 ret
= IMFMediaType_Release(media_type
);
6334 ok(ret
== 0, "Release returned %lu\n", ret
);
6335 winetest_pop_context();
6337 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6338 ok(i
== 2, "%lu output media types\n", i
);
6340 /* check required output media type attributes */
6342 hr
= MFCreateMediaType(&media_type
);
6343 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6344 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6345 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6346 init_media_type(media_type
, output_type_desc
, 1);
6347 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6348 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
6349 init_media_type(media_type
, output_type_desc
, 2);
6350 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
6352 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6353 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
6354 init_media_type(media_type
, output_type_desc
, i
+ 1);
6356 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6357 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
6358 ret
= IMFMediaType_Release(media_type
);
6359 ok(ret
== 0, "Release returned %lu\n", ret
);
6361 memset(&input_info
, 0xcd, sizeof(input_info
));
6362 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6363 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6364 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6365 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
6366 ok(input_info
.cbSize
== wmaenc_block_size
, "got cbSize %lu\n", input_info
.cbSize
);
6367 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6368 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6370 memset(&output_info
, 0xcd, sizeof(output_info
));
6371 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6372 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6373 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6375 ok(output_info
.cbSize
== 0, "got cbSize %#lx\n", output_info
.cbSize
);
6376 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6378 /* MF_MT_AUDIO_AVG_BYTES_PER_SECOND isn't required by SetInputType, but is needed for the transform to work */
6380 hr
= MFCreateMediaType(&media_type
);
6381 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6382 init_media_type(media_type
, input_type_desc
, -1);
6383 hr
= IMFMediaType_SetUINT32(media_type
, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003);
6384 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
6385 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6386 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6388 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6389 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
6391 init_media_type(media_type
, output_type_desc
, -1);
6392 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6393 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6394 ret
= IMFMediaType_Release(media_type
);
6395 ok(ret
== 0, "Release returned %lu\n", ret
);
6397 memset(&output_info
, 0xcd, sizeof(output_info
));
6398 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6399 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6400 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
6401 ok(output_info
.cbSize
== wmadec_block_size
, "got cbSize %#lx\n", output_info
.cbSize
);
6402 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6404 resource
= FindResourceW(NULL
, L
"wmaencdata.bin", (const WCHAR
*)RT_RCDATA
);
6405 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6406 wmaenc_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6407 wmaenc_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6408 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
6410 sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
6411 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6412 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6413 ret
= IMFSample_Release(sample
);
6414 ok(ret
== 0, "Release returned %lu\n", ret
);
6415 sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
6416 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6417 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6418 ret
= IMFSample_Release(sample
);
6419 ok(ret
== 0, "Release returned %lu\n", ret
);
6420 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
6421 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6422 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6423 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6424 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6425 ret
= IMFSample_Release(sample
);
6426 ok(ret
== 1, "Release returned %lu\n", ret
);
6428 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
6429 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
6431 status
= 0xdeadbeef;
6432 memset(&output
, 0, sizeof(output
));
6433 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6434 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6435 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
6436 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6437 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6438 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6439 "got dwStatus %#lx\n", output
.dwStatus
);
6440 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
6441 ok(status
== 0, "got status %#lx\n", status
);
6443 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
6444 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6445 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6446 ret
= IMFSample_Release(sample
);
6447 ok(ret
== 0, "Release returned %lu\n", ret
);
6449 status
= 0xdeadbeef;
6450 memset(&output
, 0, sizeof(output
));
6451 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6452 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6453 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
6454 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
||
6455 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
6456 "got dwStatus %#lx\n", output
.dwStatus
);
6457 ok(status
== 0, "got status %#lx\n", status
);
6459 status
= 0xdeadbeef;
6460 memset(&output
, 0, sizeof(output
));
6461 output_info
.cbSize
= wmadec_block_size
;
6462 sample
= create_sample(NULL
, output_info
.cbSize
);
6463 outputs
[0].pSample
= sample
;
6464 sample
= create_sample(NULL
, output_info
.cbSize
);
6465 outputs
[1].pSample
= sample
;
6466 hr
= IMFTransform_ProcessOutput(transform
, 0, 2, outputs
, &status
);
6467 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
6468 IMFSample_Release(outputs
[0].pSample
);
6469 IMFSample_Release(outputs
[1].pSample
);
6471 resource
= FindResourceW(NULL
, L
"wmadecdata.bin", (const WCHAR
*)RT_RCDATA
);
6472 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
6473 wmadec_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
6474 wmadec_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
6475 ok(wmadec_data_len
== wmadec_block_size
* 7 / 2, "got length %lu\n", wmadec_data_len
);
6477 /* and generate a new one as well in a temporary directory */
6478 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
6479 lstrcatW(output_path
, L
"wmadecdata.bin");
6480 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
6481 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
6483 status
= 0xdeadbeef;
6484 output_info
.cbSize
= wmadec_block_size
;
6485 sample
= create_sample(NULL
, output_info
.cbSize
);
6486 memset(&output
, 0, sizeof(output
));
6487 output
.pSample
= sample
;
6488 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6490 for (i
= 0; i
< 4; ++i
)
6492 winetest_push_context("%lu", i
);
6494 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6495 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6496 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| output
.dwStatus
== 0 ||
6497 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7) || output
.dwStatus
== 7) /* Win7 */,
6498 "got dwStatus %#lx\n", output
.dwStatus
);
6499 ok(status
== 0, "got status %#lx\n", status
);
6501 hr
= IMFSample_GetUINT32(sample
, &MFSampleExtension_CleanPoint
, &value
);
6502 ok(hr
== S_OK
, "GetUINT32 MFSampleExtension_CleanPoint returned %#lx\n", hr
);
6503 ok(value
== 1, "got MFSampleExtension_CleanPoint %u\n", value
);
6504 hr
= IMFSample_GetTotalLength(sample
, &length
);
6505 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6507 hr
= IMFSample_GetSampleFlags(sample
, &flags
);
6508 ok(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
6509 ok(flags
== 0, "got flags %#lx\n", flags
);
6511 hr
= IMFSample_GetSampleTime(sample
, &time
);
6512 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
6513 ok(time
== i
* 928798, "got time %I64d\n", time
);
6514 duration
= 0xdeadbeef;
6515 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
6516 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
6517 if (output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
||
6518 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)))
6520 ok(length
== wmadec_block_size
, "got length %lu\n", length
);
6521 ok(duration
== 928798, "got duration %I64d\n", duration
);
6522 check_sample_pcm16(sample
, wmadec_data
, output_file
, TRUE
);
6523 wmadec_data
+= wmadec_block_size
;
6524 wmadec_data_len
-= wmadec_block_size
;
6528 /* FFmpeg doesn't seem to decode WMA buffers in the same way as native */
6530 ok(length
== wmadec_block_size
/ 2, "got length %lu\n", length
);
6532 ok(duration
== 464399, "got duration %I64d\n", duration
);
6534 if (length
== wmadec_block_size
/ 2)
6535 check_sample_pcm16(sample
, wmadec_data
, output_file
, FALSE
);
6536 wmadec_data
+= length
;
6537 wmadec_data_len
-= length
;
6539 ret
= IMFSample_Release(sample
);
6540 ok(ret
== 0, "Release returned %lu\n", ret
);
6542 status
= 0xdeadbeef;
6543 sample
= create_sample(NULL
, output_info
.cbSize
);
6544 memset(&output
, 0, sizeof(output
));
6545 output
.pSample
= sample
;
6546 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6548 winetest_pop_context();
6551 ok(wmadec_data_len
== 0, "missing %#lx bytes\n", wmadec_data_len
);
6553 trace("created %s\n", debugstr_w(output_path
));
6554 CloseHandle(output_file
);
6556 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6557 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6558 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
6559 ok(status
== 0, "got status %#lx\n", status
);
6560 ret
= IMFSample_Release(sample
);
6561 ok(ret
== 0, "Release returned %lu\n", ret
);
6563 status
= 0xdeadbeef;
6564 sample
= create_sample(NULL
, output_info
.cbSize
);
6565 memset(&output
, 0, sizeof(output
));
6566 output
.pSample
= sample
;
6567 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
6568 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6569 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
6570 ok(output
.dwStatus
== 0 ||
6571 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|7)) /* Win7 */,
6572 "got dwStatus %#lx\n", output
.dwStatus
);
6573 ok(status
== 0, "got status %#lx\n", status
);
6574 hr
= IMFSample_GetTotalLength(sample
, &length
);
6575 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6576 ok(length
== 0, "got length %lu\n", length
);
6577 ret
= IMFSample_Release(sample
);
6578 ok(ret
== 0, "Release returned %lu\n", ret
);
6580 sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
6581 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
6582 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6584 ret
= IMFTransform_Release(transform
);
6585 ok(ret
== 0, "Release returned %lu\n", ret
);
6586 ret
= IMFSample_Release(sample
);
6587 ok(ret
== 0, "Release returned %lu\n", ret
);
6589 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
6590 (void **)&unknown
);
6591 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
6592 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
6593 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6594 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
6595 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6596 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
6597 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6598 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
6599 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
6601 ok( unknown
!= &outer
, "got outer IUnknown\n" );
6602 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
6603 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
6604 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
6605 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
6607 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
6608 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
6609 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
6610 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
6611 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
6612 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
6614 ref
= IUnknown_Release( tmp_unknown
);
6615 ok( ref
== 1, "Release returned %lu\n", ref
);
6616 ref
= IPropertyBag_Release( property_bag
);
6617 ok( ref
== 1, "Release returned %lu\n", ref
);
6618 ref
= IMediaObject_Release( media_object
);
6619 ok( ref
== 1, "Release returned %lu\n", ref
);
6620 ref
= IMFTransform_Release( transform
);
6621 ok( ref
== 1, "Release returned %lu\n", ref
);
6622 ref
= IUnknown_Release( unknown
);
6623 ok( ref
== 0, "Release returned %lu\n", ref
);
6629 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
6630 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
6632 const BYTE
*sample_data
;
6634 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
6635 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
6636 sample_data
= *h264_buf
;
6641 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
6647 return create_sample(sample_data
, *h264_buf
- sample_data
);
6650 static void test_h264_decoder(void)
6652 const GUID transform_inputs
[] =
6655 MFVideoFormat_H264_ES
,
6657 const GUID transform_outputs
[] =
6665 static const media_type_desc default_inputs
[] =
6668 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6669 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
6672 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6673 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
6676 static const media_type_desc default_outputs
[] =
6679 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6680 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6681 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6682 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6683 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6684 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6685 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6686 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6689 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6690 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
6691 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6692 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6693 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6694 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6695 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6696 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6699 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6700 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
6701 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6702 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6703 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6704 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6705 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6706 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6709 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6710 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6711 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6712 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6713 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 1920),
6714 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6715 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6716 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6719 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6720 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
6721 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6722 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
6723 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
6724 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6725 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6726 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6729 static const media_type_desc default_outputs_extra
[] =
6732 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6733 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6734 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6737 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6738 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6739 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6742 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6743 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6744 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6747 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6748 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3110400),
6749 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6752 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6753 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 4147200),
6754 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6757 static const media_type_desc default_outputs_win7
[] =
6760 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6761 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6764 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6765 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6768 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6769 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6772 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6773 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3133440),
6776 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6777 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 4177920),
6780 static const struct attribute_desc input_type_desc
[] =
6782 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6783 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
6786 static const struct attribute_desc minimal_output_type_desc
[] =
6788 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6789 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6790 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6793 static const struct attribute_desc output_type_desc
[] =
6795 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6796 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6797 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1080),
6798 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6799 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
6800 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
6801 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * 1080 * 3 / 2),
6802 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6805 static const struct attribute_desc output_type_desc_win7
[] =
6807 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6808 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6809 ATTR_RATIO(MF_MT_FRAME_SIZE
, 1920, 1088),
6810 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6811 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
6812 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
6813 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * 1088 * 3 / 2),
6814 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
6817 static const struct attribute_desc new_output_type_desc
[] =
6819 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6820 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6821 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
6822 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
6823 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
6826 static const struct attribute_desc new_output_type_desc_win7
[] =
6828 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6829 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6830 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
6831 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
6832 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
6835 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
6836 static const DWORD actual_width
= 96, actual_height
= 96;
6837 const media_type_desc actual_outputs
[] =
6840 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6841 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6842 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6843 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6844 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6845 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
6846 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
6847 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6848 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6849 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6850 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6851 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6854 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6855 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
6856 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6857 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6858 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6859 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
6860 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
6861 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6862 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6863 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6864 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6865 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6868 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6869 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
6870 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6871 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6872 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6873 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
6874 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
6875 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6876 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6877 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6878 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6879 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6882 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6883 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
6884 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6885 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6886 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6887 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
6888 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
6889 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6890 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6891 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6892 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6893 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6896 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6897 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
6898 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6899 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
6900 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6901 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
6902 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
6903 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
6904 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
6905 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6906 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6907 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6911 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
6912 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
6913 const BYTE
*h264_encoded_data
, *nv12_frame_data
, *i420_frame_data
;
6914 ULONG h264_encoded_data_len
, nv12_frame_len
, i420_frame_len
;
6915 DWORD input_id
, output_id
, input_count
, output_count
;
6916 MFT_OUTPUT_STREAM_INFO output_info
;
6917 MFT_INPUT_STREAM_INFO input_info
;
6918 MFT_OUTPUT_DATA_BUFFER output
;
6919 IMFMediaBuffer
*media_buffer
;
6920 DWORD status
, length
, count
;
6921 WCHAR output_path
[MAX_PATH
];
6922 IMFAttributes
*attributes
;
6923 IMFMediaType
*media_type
;
6924 LONGLONG time
, duration
;
6925 IMFTransform
*transform
;
6926 BOOL is_win7
= FALSE
;
6927 ULONG i
, ret
, flags
;
6936 hr
= CoInitialize(NULL
);
6937 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6939 if (!create_transform(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, L
"Microsoft H264 Video Decoder MFT", &MFMediaType_Video
,
6940 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
6941 &transform
, &CLSID_MSH264DecoderMFT
, &class_id
))
6944 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
6945 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
6946 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
6947 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
6948 IMFAttributes_Release(attributes
);
6950 /* no output type is available before an input type is set */
6952 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6953 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6954 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
6955 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputCurrentType returned %#lx\n", hr
);
6957 /* setting output media type first doesn't work */
6959 hr
= MFCreateMediaType(&media_type
);
6960 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
6961 init_media_type(media_type
, default_outputs
[0], -1);
6962 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6963 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
6964 ret
= IMFMediaType_Release(media_type
);
6965 ok(ret
== 0, "Release returned %lu\n", ret
);
6967 /* check available input types */
6969 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
6970 memset(&input_info
, 0xcd, sizeof(input_info
));
6971 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
6973 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
6975 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
6977 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
6979 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
6981 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
6983 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
6985 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
6986 memset(&output_info
, 0xcd, sizeof(output_info
));
6987 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
6988 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
6989 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
6990 ok(output_info
.cbSize
== 1920 * 1088 * 2, "got cbSize %#lx\n", output_info
.cbSize
);
6991 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
6994 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6996 winetest_push_context("in %lu", i
);
6997 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6998 check_media_type(media_type
, default_inputs
[i
], -1);
6999 ret
= IMFMediaType_Release(media_type
);
7000 ok(ret
== 0, "Release returned %lu\n", ret
);
7001 winetest_pop_context();
7003 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
7004 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
7006 /* check required input media type attributes */
7008 hr
= MFCreateMediaType(&media_type
);
7009 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7010 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7011 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
7012 init_media_type(media_type
, input_type_desc
, 1);
7013 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7015 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
7016 init_media_type(media_type
, input_type_desc
, 2);
7017 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7018 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
7019 ret
= IMFMediaType_Release(media_type
);
7020 ok(ret
== 1, "Release returned %lu\n", ret
);
7022 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7023 memset(&output_info
, 0xcd, sizeof(output_info
));
7024 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7025 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7026 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7028 ok(output_info
.cbSize
== 1920 * 1080 * 2 || broken(output_info
.cbSize
== 1920 * 1088 * 2) /* Win7 */,
7029 "got cbSize %#lx\n", output_info
.cbSize
);
7030 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7032 /* output types can now be enumerated (though they are actually the same for all input types) */
7035 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7037 winetest_push_context("out %lu", i
);
7038 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7039 check_media_type(media_type
, default_outputs
[i
], -1);
7040 hr
= IMFMediaType_GetItem(media_type
, &MF_MT_VIDEO_ROTATION
, NULL
);
7041 is_win7
= broken(FAILED(hr
));
7042 check_media_type(media_type
, is_win7
? default_outputs_win7
[i
] : default_outputs_extra
[i
], -1);
7043 ret
= IMFMediaType_Release(media_type
);
7044 ok(ret
== 0, "Release returned %lu\n", ret
);
7045 winetest_pop_context();
7047 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7048 ok(i
== 5, "%lu output media types\n", i
);
7050 /* check required output media type attributes */
7052 hr
= MFCreateMediaType(&media_type
);
7053 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7054 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7056 ok(hr
== E_INVALIDARG
, "SetOutputType returned %#lx.\n", hr
);
7057 init_media_type(media_type
, minimal_output_type_desc
, 1);
7058 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7060 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
7061 init_media_type(media_type
, minimal_output_type_desc
, 2);
7062 for (i
= 2; i
< ARRAY_SIZE(minimal_output_type_desc
) - 1; ++i
)
7064 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7066 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
7067 init_media_type(media_type
, minimal_output_type_desc
, i
+ 1);
7069 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7070 ok(hr
== (is_win7
? MF_E_INVALIDMEDIATYPE
: S_OK
), "SetOutputType returned %#lx.\n", hr
);
7071 init_media_type(media_type
, is_win7
? output_type_desc_win7
: output_type_desc
, -1);
7072 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7073 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7074 ret
= IMFMediaType_Release(media_type
);
7075 ok(ret
== 1, "Release returned %lu\n", ret
);
7077 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7078 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7079 check_media_type(media_type
, is_win7
? output_type_desc_win7
: output_type_desc
, -1);
7080 ret
= IMFMediaType_Release(media_type
);
7081 ok(ret
== 0, "Release returned %lu\n", ret
);
7083 /* check that the output media type we've selected don't change the enumeration */
7086 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7088 winetest_push_context("out %lu", i
);
7089 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7090 check_media_type(media_type
, default_outputs
[i
], -1);
7091 check_media_type(media_type
, is_win7
? default_outputs_win7
[i
] : default_outputs_extra
[i
], -1);
7092 ret
= IMFMediaType_Release(media_type
);
7093 ok(ret
== 0, "Release returned %lu\n", ret
);
7094 winetest_pop_context();
7096 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7097 ok(i
== 5, "%lu output media types\n", i
);
7099 flags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
;
7100 memset(&input_info
, 0xcd, sizeof(input_info
));
7101 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7102 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
7103 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
7104 ok(input_info
.dwFlags
== flags
, "got dwFlags %#lx\n", input_info
.dwFlags
);
7105 ok(input_info
.cbSize
== 0x1000, "got cbSize %lu\n", input_info
.cbSize
);
7106 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
7107 ok(input_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
7109 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7110 memset(&output_info
, 0xcd, sizeof(output_info
));
7111 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7112 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7113 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7115 ok(output_info
.cbSize
== 1920 * 1080 * 2 || broken(output_info
.cbSize
== 1920 * 1088 * 2) /* Win7 */,
7116 "got cbSize %#lx\n", output_info
.cbSize
);
7117 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7119 input_count
= output_count
= 0xdeadbeef;
7120 hr
= IMFTransform_GetStreamCount(transform
, &input_count
, &output_count
);
7122 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
7124 ok(input_count
== 1, "got input_count %lu\n", input_count
);
7126 ok(output_count
== 1, "got output_count %lu\n", output_count
);
7127 hr
= IMFTransform_GetStreamIDs(transform
, 1, &input_id
, 1, &output_id
);
7128 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
7130 resource
= FindResourceW(NULL
, L
"h264data.bin", (const WCHAR
*)RT_RCDATA
);
7131 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7132 h264_encoded_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7133 h264_encoded_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7135 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
7136 * IMFTransform_ProcessOutput needs a sample or returns an error */
7139 memset(&output
, 0, sizeof(output
));
7140 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7141 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7142 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7143 ok(!output
.pSample
, "got pSample %p\n", output
.pSample
);
7144 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7145 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7146 ok(status
== 0, "got status %#lx\n", status
);
7149 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7153 memset(&output
, 0, sizeof(output
));
7154 output
.pSample
= create_sample(NULL
, output_info
.cbSize
);
7155 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7156 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
7157 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7158 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7159 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7160 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7161 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7162 ok(status
== 0, "got status %#lx\n", status
);
7163 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7164 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7165 ok(length
== 0, "got length %lu\n", length
);
7166 ret
= IMFSample_Release(output
.pSample
);
7167 ok(ret
== 0, "Release returned %lu\n", ret
);
7169 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7170 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7171 ret
= IMFSample_Release(sample
);
7172 ok(ret
<= 1, "Release returned %lu\n", ret
);
7173 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7175 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7176 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7177 ret
= IMFSample_Release(sample
);
7178 ok(ret
<= 1, "Release returned %lu\n", ret
);
7179 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7182 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
7183 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
7186 ok(i
== 2, "got %lu iterations\n", i
);
7188 ok(h264_encoded_data_len
== 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
7189 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7190 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7191 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7192 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
,
7193 "got dwStatus %#lx\n", output
.dwStatus
);
7194 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7195 ok(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
7196 "got status %#lx\n", status
);
7197 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7198 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7199 ok(length
== 0, "got length %lu\n", length
);
7200 ret
= IMFSample_Release(output
.pSample
);
7201 ok(ret
== 0, "Release returned %lu\n", ret
);
7203 flags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
;
7204 memset(&output_info
, 0xcd, sizeof(output_info
));
7205 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7206 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7207 ok(output_info
.dwFlags
== flags
, "got dwFlags %#lx\n", output_info
.dwFlags
);
7208 ok(output_info
.cbSize
== actual_width
* actual_height
* 2, "got cbSize %#lx\n", output_info
.cbSize
);
7209 ok(output_info
.cbAlignment
== 0, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7212 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7214 winetest_push_context("out %lu", i
);
7215 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7216 check_media_type(media_type
, actual_outputs
[i
], -1);
7217 ret
= IMFMediaType_Release(media_type
);
7218 ok(ret
== 0, "Release returned %lu\n", ret
);
7219 winetest_pop_context();
7221 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7222 ok(i
== 5, "%lu output media types\n", i
);
7224 /* current output type is still the one we selected */
7225 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7226 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7227 check_media_type(media_type
, is_win7
? output_type_desc_win7
: output_type_desc
, -1);
7228 hr
= IMFMediaType_GetItemType(media_type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, NULL
);
7229 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetItemType returned %#lx\n", hr
);
7230 ret
= IMFMediaType_Release(media_type
);
7231 ok(ret
== 0, "Release returned %lu\n", ret
);
7233 /* and generate a new one as well in a temporary directory */
7234 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
7235 lstrcatW(output_path
, L
"nv12frame.bin");
7236 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
7237 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
7239 resource
= FindResourceW(NULL
, L
"nv12frame.bin", (const WCHAR
*)RT_RCDATA
);
7240 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7241 nv12_frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7242 nv12_frame_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7243 ok(nv12_frame_len
== actual_width
* actual_height
* 3 / 2, "got frame length %lu\n", nv12_frame_len
);
7246 memset(&output
, 0, sizeof(output
));
7247 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7248 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7249 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7250 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7251 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7252 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7253 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7254 ok(status
== 0, "got status %#lx\n", status
);
7256 hr
= IMFSample_GetUINT32(sample
, &MFSampleExtension_CleanPoint
, &value
);
7257 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetUINT32 MFSampleExtension_CleanPoint returned %#lx\n", hr
);
7260 hr
= IMFSample_GetBufferCount(output
.pSample
, &count
);
7261 ok(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
7262 ok(count
== 1, "got count %#lx\n", count
);
7265 hr
= IMFSample_GetSampleFlags(output
.pSample
, &flags
);
7266 ok(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
7267 ok(flags
== 0, "got flags %#lx\n", flags
);
7270 hr
= IMFSample_GetSampleTime(output
.pSample
, &time
);
7271 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7272 ok(time
== 0, "got time %I64d\n", time
);
7274 /* doesn't matter what frame rate we've selected, duration is defined by the stream */
7275 duration
= 0xdeadbeef;
7276 hr
= IMFSample_GetSampleDuration(output
.pSample
, &duration
);
7277 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7278 ok(duration
- 333666 <= 2, "got duration %I64d\n", duration
);
7280 /* Win8 and before pad the data with garbage instead of original
7281 * buffer data, make sure it's consistent. */
7282 hr
= IMFSample_ConvertToContiguousBuffer(output
.pSample
, &media_buffer
);
7283 ok(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
7284 hr
= IMFMediaBuffer_Lock(media_buffer
, &data
, NULL
, &length
);
7285 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
7286 ok(length
== nv12_frame_len
, "got length %lu\n", length
);
7288 for (i
= 0; i
< actual_aperture
.Area
.cy
; ++i
)
7290 memset(data
+ actual_width
* i
+ actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7291 memset(data
+ actual_width
* (actual_height
+ i
) + actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7293 memset(data
+ actual_width
* actual_aperture
.Area
.cy
, 0xcd, (actual_height
- actual_aperture
.Area
.cy
) * actual_width
);
7294 memset(data
+ actual_width
* (actual_height
+ actual_aperture
.Area
.cy
/ 2), 0xcd, (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
);
7296 hr
= IMFMediaBuffer_Unlock(media_buffer
);
7297 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
7298 IMFMediaBuffer_Release(media_buffer
);
7300 check_sample(output
.pSample
, nv12_frame_data
, output_file
);
7302 ret
= IMFSample_Release(output
.pSample
);
7303 ok(ret
== 0, "Release returned %lu\n", ret
);
7305 trace("created %s\n", debugstr_w(output_path
));
7306 CloseHandle(output_file
);
7308 /* we can change it, but only with the correct frame size */
7309 hr
= MFCreateMediaType(&media_type
);
7310 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7311 init_media_type(media_type
, is_win7
? output_type_desc_win7
: output_type_desc
, -1);
7312 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7313 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
7314 init_media_type(media_type
, is_win7
? new_output_type_desc_win7
: new_output_type_desc
, -1);
7315 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7316 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7317 ret
= IMFMediaType_Release(media_type
);
7318 ok(ret
== 1, "Release returned %lu\n", ret
);
7320 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type
);
7321 ok(hr
== S_OK
, "GetOutputCurrentType returned %#lx\n", hr
);
7322 check_media_type(media_type
, is_win7
? new_output_type_desc_win7
: new_output_type_desc
, -1);
7323 hr
= IMFMediaType_GetItemType(media_type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, NULL
);
7324 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "GetItemType returned %#lx\n", hr
);
7325 ret
= IMFMediaType_Release(media_type
);
7326 ok(ret
== 0, "Release returned %lu\n", ret
);
7329 memset(&output
, 0, sizeof(output
));
7330 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7331 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7333 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7335 if (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
7337 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7338 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7339 ret
= IMFSample_Release(sample
);
7340 ok(ret
<= 1, "Release returned %lu\n", ret
);
7341 sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
7342 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7344 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
7347 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7348 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7350 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got dwStatus %#lx\n", output
.dwStatus
);
7351 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7353 ok(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
, "got status %#lx\n", status
);
7354 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
7355 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7356 ok(length
== 0, "got length %lu\n", length
);
7357 ret
= IMFSample_Release(output
.pSample
);
7358 ok(ret
== 0, "Release returned %lu\n", ret
);
7360 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
7361 lstrcatW(output_path
, L
"i420frame.bin");
7362 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
7363 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
7365 resource
= FindResourceW(NULL
, L
"i420frame.bin", (const WCHAR
*)RT_RCDATA
);
7366 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7367 i420_frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7368 i420_frame_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7369 ok(i420_frame_len
== actual_width
* actual_height
* 3 / 2, "got frame length %lu\n", i420_frame_len
);
7372 memset(&output
, 0, sizeof(output
));
7373 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7374 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7376 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7377 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7378 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7379 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7380 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7381 ok(status
== 0, "got status %#lx\n", status
);
7382 if (hr
!= S_OK
) goto skip_i420_tests
;
7384 hr
= IMFSample_GetSampleTime(output
.pSample
, &time
);
7385 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7386 ok(time
- 333666 <= 2, "got time %I64d\n", time
);
7388 duration
= 0xdeadbeef;
7389 hr
= IMFSample_GetSampleDuration(output
.pSample
, &duration
);
7390 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7391 ok(duration
- 333666 <= 2, "got duration %I64d\n", duration
);
7393 /* Win8 and before pad the data with garbage instead of original
7394 * buffer data, make sure it's consistent. */
7395 hr
= IMFSample_ConvertToContiguousBuffer(output
.pSample
, &media_buffer
);
7396 ok(hr
== S_OK
, "ConvertToContiguousBuffer returned %#lx\n", hr
);
7397 hr
= IMFMediaBuffer_Lock(media_buffer
, &data
, NULL
, &length
);
7398 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
7399 ok(length
== i420_frame_len
, "got length %lu\n", length
);
7401 for (i
= 0; i
< actual_aperture
.Area
.cy
; ++i
)
7403 memset(data
+ actual_width
* i
+ actual_aperture
.Area
.cx
, 0xcd, actual_width
- actual_aperture
.Area
.cx
);
7404 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * i
+ actual_aperture
.Area
.cx
/ 2, 0xcd,
7405 actual_width
/ 2 - actual_aperture
.Area
.cx
/ 2);
7406 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * (actual_height
/ 2 + i
) + actual_aperture
.Area
.cx
/ 2, 0xcd,
7407 actual_width
/ 2 - actual_aperture
.Area
.cx
/ 2);
7409 memset(data
+ actual_width
* actual_aperture
.Area
.cy
, 0xcd, (actual_height
- actual_aperture
.Area
.cy
) * actual_width
);
7410 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * actual_aperture
.Area
.cy
/ 2, 0xcd,
7411 (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
/ 2);
7412 memset(data
+ actual_width
* actual_height
+ actual_width
/ 2 * (actual_height
/ 2 + actual_aperture
.Area
.cy
/ 2), 0xcd,
7413 (actual_height
- actual_aperture
.Area
.cy
) / 2 * actual_width
/ 2);
7415 hr
= IMFMediaBuffer_Unlock(media_buffer
);
7416 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
7417 IMFMediaBuffer_Release(media_buffer
);
7419 check_sample(output
.pSample
, i420_frame_data
, output_file
);
7422 ret
= IMFSample_Release(output
.pSample
);
7423 ok(ret
== 0, "Release returned %lu\n", ret
);
7425 trace("created %s\n", debugstr_w(output_path
));
7426 CloseHandle(output_file
);
7429 memset(&output
, 0, sizeof(output
));
7430 output
.pSample
= create_sample(NULL
, actual_width
* actual_height
* 2);
7431 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7432 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7433 ok(output
.dwStreamID
== 0, "got dwStreamID %lu\n", output
.dwStreamID
);
7434 ok(!!output
.pSample
, "got pSample %p\n", output
.pSample
);
7435 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7436 ok(!output
.pEvents
, "got pEvents %p\n", output
.pEvents
);
7437 ok(status
== 0, "got status %#lx\n", status
);
7438 ret
= IMFSample_Release(output
.pSample
);
7439 ok(ret
== 0, "Release returned %lu\n", ret
);
7441 ret
= IMFTransform_Release(transform
);
7442 ok(ret
== 0, "Release returned %lu\n", ret
);
7443 ret
= IMFSample_Release(sample
);
7444 ok(ret
== 0, "Release returned %lu\n", ret
);
7450 static void test_audio_convert(void)
7452 const GUID transform_inputs
[2] =
7455 MFAudioFormat_Float
,
7457 const GUID transform_outputs
[2] =
7460 MFAudioFormat_Float
,
7463 static const media_type_desc expect_available_inputs
[] =
7466 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7467 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7468 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7471 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7472 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7473 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7476 static const media_type_desc expect_available_outputs
[] =
7479 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7480 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7481 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7484 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7485 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7486 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7489 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7490 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7491 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7492 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7493 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
7494 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
7495 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
7496 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7497 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7500 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7501 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7502 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7503 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7504 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
7505 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
7506 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7507 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7508 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7512 static const struct attribute_desc input_type_desc
[] =
7514 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7515 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7516 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7517 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7518 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7519 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
7520 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
7523 const struct attribute_desc output_type_desc
[] =
7525 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7526 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7527 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7528 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7529 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
7530 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
7531 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7535 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
7536 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
7537 static const ULONG audioconv_block_size
= 0x4000;
7538 ULONG audio_data_len
, audioconv_data_len
;
7539 const BYTE
*audio_data
, *audioconv_data
;
7540 MFT_OUTPUT_STREAM_INFO output_info
;
7541 MFT_INPUT_STREAM_INFO input_info
;
7542 MFT_OUTPUT_DATA_BUFFER output
;
7543 WCHAR output_path
[MAX_PATH
];
7544 IMFMediaType
*media_type
;
7545 LONGLONG time
, duration
;
7546 IMFTransform
*transform
;
7547 DWORD length
, status
;
7555 hr
= CoInitialize(NULL
);
7556 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
7558 if (!create_transform(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, L
"Resampler MFT", &MFMediaType_Audio
,
7559 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
7560 &transform
, &CLSID_CResamplerMediaObject
, &class_id
))
7563 check_dmo(&class_id
, L
"Resampler DMO", &MEDIATYPE_Audio
, transform_inputs
, ARRAY_SIZE(transform_inputs
),
7564 transform_outputs
, ARRAY_SIZE(transform_outputs
));
7566 check_interface(transform
, &IID_IMFTransform
, TRUE
);
7567 check_interface(transform
, &IID_IMediaObject
, TRUE
);
7568 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
7570 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
7571 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
7573 /* check default media types */
7575 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7576 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
7577 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7578 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
7581 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7583 winetest_push_context("out %lu", i
);
7584 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7585 check_media_type(media_type
, expect_available_outputs
[i
], -1);
7586 ret
= IMFMediaType_Release(media_type
);
7587 ok(ret
== 0, "Release returned %lu\n", ret
);
7588 winetest_pop_context();
7590 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7591 ok(i
== 4, "%lu output media types\n", i
);
7594 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
7596 winetest_push_context("in %lu", i
);
7597 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
7598 check_media_type(media_type
, expect_available_inputs
[i
], -1);
7599 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7600 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
7601 ret
= IMFMediaType_Release(media_type
);
7602 ok(ret
== 0, "Release returned %lu\n", ret
);
7603 winetest_pop_context();
7605 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
7606 ok(i
== 2, "%lu input media types\n", i
);
7608 /* setting output media type first doesn't work */
7610 hr
= MFCreateMediaType(&media_type
);
7611 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7612 init_media_type(media_type
, output_type_desc
, -1);
7613 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7614 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
7615 ret
= IMFMediaType_Release(media_type
);
7616 ok(ret
== 0, "Release returned %lu\n", ret
);
7618 /* check required input media type attributes */
7620 hr
= MFCreateMediaType(&media_type
);
7621 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7622 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7623 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
7624 init_media_type(media_type
, input_type_desc
, 1);
7625 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7626 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
7627 init_media_type(media_type
, input_type_desc
, 2);
7628 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
7630 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7631 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
7632 init_media_type(media_type
, input_type_desc
, i
+ 1);
7634 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
7635 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
7636 ret
= IMFMediaType_Release(media_type
);
7637 ok(ret
== 0, "Release returned %lu\n", ret
);
7639 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7640 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
7641 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7642 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
7644 /* check new output media types */
7647 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7649 winetest_push_context("out %lu", i
);
7650 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7651 check_media_type(media_type
, expect_available_outputs
[i
], -1);
7652 ret
= IMFMediaType_Release(media_type
);
7653 ok(ret
== 0, "Release returned %lu\n", ret
);
7654 winetest_pop_context();
7656 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7657 ok(i
== 4, "%lu output media types\n", i
);
7659 /* check required output media type attributes */
7661 hr
= MFCreateMediaType(&media_type
);
7662 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
7663 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7664 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
7665 init_media_type(media_type
, output_type_desc
, 1);
7666 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7667 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
7668 init_media_type(media_type
, output_type_desc
, 2);
7669 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
7671 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7672 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
7673 init_media_type(media_type
, output_type_desc
, i
+ 1);
7675 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
7676 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
7677 ret
= IMFMediaType_Release(media_type
);
7678 ok(ret
== 0, "Release returned %lu\n", ret
);
7680 memset(&input_info
, 0xcd, sizeof(input_info
));
7681 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
7682 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
7683 ok(input_info
.hnsMaxLatency
== 0, "got hnsMaxLatency %s\n", wine_dbgstr_longlong(input_info
.hnsMaxLatency
));
7684 ok(input_info
.dwFlags
== 0, "got dwFlags %#lx\n", input_info
.dwFlags
);
7685 ok(input_info
.cbSize
== 8, "got cbSize %lu\n", input_info
.cbSize
);
7686 ok(input_info
.cbMaxLookahead
== 0, "got cbMaxLookahead %#lx\n", input_info
.cbMaxLookahead
);
7687 ok(input_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", input_info
.cbAlignment
);
7689 memset(&output_info
, 0xcd, sizeof(output_info
));
7690 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
7691 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
7692 ok(output_info
.dwFlags
== 0, "got dwFlags %#lx\n", output_info
.dwFlags
);
7693 ok(output_info
.cbSize
== 4, "got cbSize %#lx\n", output_info
.cbSize
);
7694 ok(output_info
.cbAlignment
== 1, "got cbAlignment %#lx\n", output_info
.cbAlignment
);
7696 resource
= FindResourceW(NULL
, L
"audiodata.bin", (const WCHAR
*)RT_RCDATA
);
7697 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7698 audio_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7699 audio_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7700 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
7702 sample
= create_sample(audio_data
, audio_data_len
);
7703 hr
= IMFSample_SetSampleTime(sample
, 0);
7704 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
7705 hr
= IMFSample_SetSampleDuration(sample
, 10000000);
7706 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
7707 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7708 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7709 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
7710 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
7711 hr
= IMFTransform_ProcessInput(transform
, 0, sample
, 0);
7712 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
7713 IMFSample_Release(sample
);
7715 status
= 0xdeadbeef;
7716 sample
= create_sample(NULL
, audioconv_block_size
);
7717 memset(&output
, 0, sizeof(output
));
7718 output
.pSample
= sample
;
7720 resource
= FindResourceW(NULL
, L
"audioconvdata.bin", (const WCHAR
*)RT_RCDATA
);
7721 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
7722 audioconv_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
7723 audioconv_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
7724 ok(audioconv_data_len
== 179924, "got length %lu\n", audioconv_data_len
);
7726 /* and generate a new one as well in a temporary directory */
7727 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
7728 lstrcatW(output_path
, L
"audioconvdata.bin");
7729 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
7730 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
7733 while (SUCCEEDED(hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
)))
7735 winetest_push_context("%lu", i
);
7736 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7737 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
7738 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| output
.dwStatus
== 0 ||
7739 broken(output
.dwStatus
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|6) || output
.dwStatus
== 6) /* win7 */,
7740 "got dwStatus %#lx\n", output
.dwStatus
);
7741 ok(status
== 0, "got status %#lx\n", status
);
7742 if (!(output
.dwStatus
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
))
7744 winetest_pop_context();
7748 hr
= IMFSample_GetSampleTime(sample
, &time
);
7749 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7750 ok(time
== i
* 928798, "got time %I64d\n", time
);
7751 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
7752 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7753 ok(duration
== 928798, "got duration %I64d\n", duration
);
7754 hr
= IMFSample_GetTotalLength(sample
, &length
);
7755 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7756 ok(length
== audioconv_block_size
, "got length %lu\n", length
);
7757 ok(audioconv_data_len
> audioconv_block_size
, "got remaining length %lu\n", audioconv_data_len
);
7758 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
7759 audioconv_data_len
-= audioconv_block_size
;
7760 audioconv_data
+= audioconv_block_size
;
7762 winetest_pop_context();
7766 hr
= IMFSample_GetSampleTime(sample
, &time
);
7767 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7768 ok(time
== i
* 928798, "got time %I64d\n", time
);
7769 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
7770 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7772 ok(duration
== 897506, "got duration %I64d\n", duration
);
7773 hr
= IMFSample_GetTotalLength(sample
, &length
);
7774 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7776 ok(length
== 15832, "got length %lu\n", length
);
7777 ok(audioconv_data_len
== 16084, "got remaining length %lu\n", audioconv_data_len
);
7778 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
7779 audioconv_data_len
-= length
;
7780 audioconv_data
+= length
;
7782 memset(&output
, 0, sizeof(output
));
7783 output
.pSample
= sample
;
7784 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7786 ok(hr
== S_OK
|| broken(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
) /* win7 */, "ProcessOutput returned %#lx\n", hr
);
7787 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
7789 ok(output
.dwStatus
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|| broken(output
.dwStatus
== 0) /* win7 */,
7790 "got dwStatus %#lx\n", output
.dwStatus
);
7791 ok(status
== 0, "got status %#lx\n", status
);
7795 hr
= IMFSample_GetSampleTime(sample
, &time
);
7796 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
7798 ok(time
== 10185486, "got time %I64d\n", time
);
7799 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
7800 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
7802 ok(duration
== 14286, "got duration %I64d\n", duration
);
7803 hr
= IMFSample_GetTotalLength(sample
, &length
);
7804 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7806 ok(length
== audioconv_data_len
, "got length %lu\n", length
);
7807 if (length
== audioconv_data_len
)
7808 check_sample_pcm16(sample
, audioconv_data
, output_file
, FALSE
);
7811 trace("created %s\n", debugstr_w(output_path
));
7812 CloseHandle(output_file
);
7814 ret
= IMFSample_Release(sample
);
7815 ok(ret
== 0, "Release returned %lu\n", ret
);
7817 status
= 0xdeadbeef;
7818 sample
= create_sample(NULL
, audioconv_block_size
);
7819 memset(&output
, 0, sizeof(output
));
7820 output
.pSample
= sample
;
7821 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
7822 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7823 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
7824 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
7825 ok(status
== 0, "got status %#lx\n", status
);
7826 hr
= IMFSample_GetTotalLength(sample
, &length
);
7827 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7828 ok(length
== 0, "got length %lu\n", length
);
7829 ret
= IMFSample_Release(sample
);
7830 ok(ret
== 0, "Release returned %lu\n", ret
);
7832 ret
= IMFTransform_Release(transform
);
7833 ok(ret
== 0, "Release returned %lu\n", ret
);
7839 static void test_color_convert(void)
7841 const GUID transform_inputs
[20] =
7848 DMOVideoFormat_RGB32
,
7849 DMOVideoFormat_RGB565
,
7853 DMOVideoFormat_RGB24
,
7854 DMOVideoFormat_RGB555
,
7855 DMOVideoFormat_RGB8
,
7864 const GUID transform_outputs
[16] =
7871 DMOVideoFormat_RGB32
,
7872 DMOVideoFormat_RGB565
,
7876 DMOVideoFormat_RGB24
,
7877 DMOVideoFormat_RGB555
,
7878 DMOVideoFormat_RGB8
,
7883 const GUID dmo_inputs
[20] =
7891 MEDIASUBTYPE_RGB565
,
7896 MEDIASUBTYPE_RGB555
,
7906 const GUID dmo_outputs
[16] =
7914 MEDIASUBTYPE_RGB565
,
7919 MEDIASUBTYPE_RGB555
,
7926 static const media_type_desc expect_available_inputs
[20] =
7928 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
7929 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
7930 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
7931 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
7932 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
7933 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
7934 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
7935 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
7936 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
7937 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
7938 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
7939 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
7940 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
7941 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
7942 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
7943 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
7944 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
7945 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
7946 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
7947 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
7949 static const media_type_desc expect_available_outputs
[16] =
7951 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
7952 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
7953 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
7954 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
7955 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
7956 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
7957 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
7958 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
7959 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
7960 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
7961 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
7962 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
7963 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
7964 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
7965 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
7966 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
7968 static const media_type_desc expect_available_common
=
7970 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7971 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
7972 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7975 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
7976 static const DWORD actual_width
= 96, actual_height
= 96;
7977 const struct attribute_desc input_type_desc
[] =
7979 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7980 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
7981 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
7982 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7985 const struct attribute_desc output_type_desc
[] =
7987 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
7988 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
7989 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
7993 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
7994 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
7995 ULONG nv12frame_data_len
, rgb32_data_len
;
7996 const BYTE
*nv12frame_data
, *rgb32_data
;
7997 MFT_OUTPUT_STREAM_INFO output_info
;
7998 MFT_INPUT_STREAM_INFO input_info
;
7999 MFT_OUTPUT_DATA_BUFFER output
;
8000 WCHAR output_path
[MAX_PATH
];
8001 IMFMediaType
*media_type
;
8002 LONGLONG time
, duration
;
8003 IMFTransform
*transform
;
8004 DWORD length
, status
;
8012 hr
= CoInitialize(NULL
);
8013 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
8015 if (!create_transform(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, L
"Color Converter MFT", &MFMediaType_Video
,
8016 transform_inputs
, ARRAY_SIZE(transform_inputs
), transform_outputs
, ARRAY_SIZE(transform_outputs
),
8017 &transform
, &CLSID_CColorConvertDMO
, &class_id
))
8020 check_dmo(&CLSID_CColorConvertDMO
, L
"Color Converter DMO", &MEDIATYPE_Video
, dmo_inputs
, ARRAY_SIZE(dmo_inputs
),
8021 dmo_outputs
, ARRAY_SIZE(dmo_outputs
));
8023 check_interface(transform
, &IID_IMFTransform
, TRUE
);
8024 check_interface(transform
, &IID_IMediaObject
, TRUE
);
8025 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
8026 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
8027 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
8029 /* check default media types */
8031 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &input_info
);
8032 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetInputStreamInfo returned %#lx\n", hr
);
8033 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &output_info
);
8034 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputStreamInfo returned %#lx\n", hr
);
8037 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
8039 winetest_push_context("out %lu", i
);
8040 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
8041 check_media_type(media_type
, expect_available_common
, -1);
8042 check_media_type(media_type
, expect_available_outputs
[i
], -1);
8043 ret
= IMFMediaType_Release(media_type
);
8044 ok(ret
== 0, "Release returned %lu\n", ret
);
8045 winetest_pop_context();
8047 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
8048 ok(i
== 16, "%lu output media types\n", i
);
8051 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
8053 winetest_push_context("in %lu", i
);
8054 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
8055 check_media_type(media_type
, expect_available_common
, -1);
8056 check_media_type(media_type
, expect_available_inputs
[i
], -1);
8057 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8061 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetInputType returned %#lx.\n", hr
);
8064 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
8065 ret
= IMFMediaType_Release(media_type
);
8066 ok(ret
== 0, "Release returned %lu\n", ret
);
8067 winetest_pop_context();
8069 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
8070 ok(i
== 20, "%lu input media types\n", i
);
8072 /* check required output media type attributes */
8074 hr
= MFCreateMediaType(&media_type
);
8075 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8076 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8077 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8078 init_media_type(media_type
, output_type_desc
, 1);
8079 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8080 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetOutputType returned %#lx.\n", hr
);
8081 init_media_type(media_type
, output_type_desc
, 2);
8082 for (i
= 2; i
< ARRAY_SIZE(output_type_desc
) - 1; ++i
)
8084 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8085 ok(hr
== E_INVALIDARG
, "SetOutputType returned %#lx.\n", hr
);
8086 init_media_type(media_type
, output_type_desc
, i
+ 1);
8088 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
8089 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
8090 ret
= IMFMediaType_Release(media_type
);
8091 ok(ret
== 0, "Release returned %lu\n", ret
);
8093 /* check required input media type attributes */
8095 hr
= MFCreateMediaType(&media_type
);
8096 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
8097 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8098 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8099 init_media_type(media_type
, input_type_desc
, 1);
8100 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8101 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
8102 init_media_type(media_type
, input_type_desc
, 2);
8103 for (i
= 2; i
< ARRAY_SIZE(input_type_desc
) - 1; ++i
)
8105 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8106 ok(hr
== E_INVALIDARG
, "SetInputType returned %#lx.\n", hr
);
8107 init_media_type(media_type
, input_type_desc
, i
+ 1);
8109 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
8110 ok(hr
== S_OK
, "SetInputType 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
== actual_width
* actual_height
* 3 / 2, "got cbSize %#lx\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
== actual_width
* actual_height
* 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
"nv12frame.bin", (const WCHAR
*)RT_RCDATA
);
8131 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8132 nv12frame_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8133 nv12frame_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8134 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
8136 sample
= create_sample(nv12frame_data
, nv12frame_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_ProcessInput(transform
, 0, sample
, 0);
8144 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
8145 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
8146 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
8147 IMFSample_Release(sample
);
8149 resource
= FindResourceW(NULL
, L
"rgb32frame.bin", (const WCHAR
*)RT_RCDATA
);
8150 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
8151 rgb32_data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
8152 rgb32_data_len
= SizeofResource(GetModuleHandleW(NULL
), resource
);
8153 ok(rgb32_data_len
== output_info
.cbSize
, "got length %lu\n", rgb32_data_len
);
8155 /* and generate a new one as well in a temporary directory */
8156 GetTempPathW(ARRAY_SIZE(output_path
), output_path
);
8157 lstrcatW(output_path
, L
"rgb32frame.bin");
8158 output_file
= CreateFileW(output_path
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
8159 ok(output_file
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
8161 status
= 0xdeadbeef;
8162 sample
= create_sample(NULL
, output_info
.cbSize
);
8163 memset(&output
, 0, sizeof(output
));
8164 output
.pSample
= sample
;
8165 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8166 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
8167 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8168 ok(output
.dwStatus
== 0 || broken(output
.dwStatus
== 6) /* win7 */, "got dwStatus %#lx\n", output
.dwStatus
);
8169 ok(status
== 0, "got status %#lx\n", status
);
8171 hr
= IMFSample_GetSampleTime(sample
, &time
);
8172 ok(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
8173 ok(time
== 0, "got time %I64d\n", time
);
8174 hr
= IMFSample_GetSampleDuration(sample
, &duration
);
8175 ok(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
8176 ok(duration
== 10000000, "got duration %I64d\n", duration
);
8177 hr
= IMFSample_GetTotalLength(sample
, &length
);
8178 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8179 ok(length
== output_info
.cbSize
, "got length %lu\n", length
);
8180 check_sample_rgb32(sample
, rgb32_data
, output_file
);
8181 rgb32_data_len
-= output_info
.cbSize
;
8182 rgb32_data
+= output_info
.cbSize
;
8184 trace("created %s\n", debugstr_w(output_path
));
8185 CloseHandle(output_file
);
8187 ret
= IMFSample_Release(sample
);
8188 ok(ret
== 0, "Release returned %lu\n", ret
);
8190 status
= 0xdeadbeef;
8191 sample
= create_sample(NULL
, output_info
.cbSize
);
8192 memset(&output
, 0, sizeof(output
));
8193 output
.pSample
= sample
;
8194 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
8195 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
8196 ok(output
.pSample
== sample
, "got pSample %p\n", output
.pSample
);
8197 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
8198 ok(status
== 0, "got status %#lx\n", status
);
8199 hr
= IMFSample_GetTotalLength(sample
, &length
);
8200 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
8201 ok(length
== 0, "got length %lu\n", length
);
8202 ret
= IMFSample_Release(sample
);
8203 ok(ret
== 0, "Release returned %lu\n", ret
);
8205 IMFTransform_Release(transform
);
8218 win_skip("Skipping tests on Vista.\n");
8222 test_video_processor();
8224 test_topology_tee_node();
8225 test_topology_loader();
8226 test_topology_loader_evr();
8227 test_MFGetService();
8228 test_sequencer_source();
8229 test_media_session();
8230 test_media_session_rate_control();
8231 test_MFShutdownObject();
8232 test_presentation_clock();
8233 test_sample_grabber();
8234 test_sample_grabber_is_mediatype_supported();
8235 test_quality_manager();
8238 test_MFCreateSimpleTypeHandler();
8239 test_MFGetSupportedMimeTypes();
8240 test_MFGetSupportedSchemes();
8241 test_sample_copier();
8242 test_sample_copier_output_processing();
8243 test_MFGetTopoNodeCurrentType();
8244 test_MFRequireProtectedEnvironment();
8247 test_h264_decoder();
8248 test_audio_convert();
8249 test_color_convert();