2 * Copyright 2017 Nikolay Sivov
3 * Copyright 2022 RĂ©mi Bernon for CodeWeavers
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "d3d9types.h"
32 #include "mftransform.h"
33 #include "propvarutil.h"
35 #include "wmcodecdsp.h"
39 #include "wine/test.h"
43 DEFINE_GUID(DMOVideoFormat_RGB24
,D3DFMT_R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
44 DEFINE_GUID(DMOVideoFormat_RGB32
,D3DFMT_X8R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
45 DEFINE_GUID(DMOVideoFormat_RGB555
,D3DFMT_X1R5G5B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
46 DEFINE_GUID(DMOVideoFormat_RGB565
,D3DFMT_R5G6B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
47 DEFINE_GUID(DMOVideoFormat_RGB8
,D3DFMT_P8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
48 DEFINE_GUID(MFAudioFormat_RAW_AAC1
,WAVE_FORMAT_RAW_AAC1
,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
49 DEFINE_GUID(MFVideoFormat_ABGR32
,0x00000020,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
50 DEFINE_GUID(MFVideoFormat_P208
,0x38303250,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
51 DEFINE_GUID(MFVideoFormat_VC1S
,0x53314356,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
52 DEFINE_GUID(MFVideoFormat_WMV_Unknown
,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b);
54 DEFINE_GUID(mft_output_sample_incomplete
,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
56 static void load_resource(const WCHAR
*filename
, const BYTE
**data
, DWORD
*length
)
58 HRSRC resource
= FindResourceW(NULL
, filename
, (const WCHAR
*)RT_RCDATA
);
59 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
60 *data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
61 *length
= SizeofResource(GetModuleHandleW(NULL
), resource
);
64 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
65 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
69 refcount
= IUnknown_Release(obj
);
70 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
74 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
75 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
77 IUnknown
*iface
= iface_ptr
;
78 HRESULT hr
, expected_hr
;
81 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
83 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
84 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
86 IUnknown_Release(unk
);
89 #define check_member_(file, line, val, exp, fmt, member) \
90 ok_ (file, line)((val).member == (exp).member, "got " #member " " fmt "\n", (val).member)
91 #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
93 void check_attributes_(int line
, IMFAttributes
*attributes
, const struct attribute_desc
*desc
, ULONG limit
)
95 char buffer
[256], *buf
= buffer
;
100 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
102 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
103 todo_wine_if(desc
[i
].todo
)
104 ok_(__FILE__
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
105 if (hr
!= S_OK
) continue;
109 default: sprintf(buffer
, "??"); break;
110 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
111 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
114 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
116 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
118 case VT_VECTOR
| VT_UI1
:
119 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
120 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
121 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
122 if (value
.caub
.cElems
> 16)
123 buf
+= sprintf(buf
, "...}");
125 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
129 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
130 todo_wine_if(desc
[i
].todo_value
)
131 ok_(__FILE__
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
132 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
136 struct transform_info
139 const GUID
*major_type
;
144 } inputs
[32], input_end
, outputs
[32], output_end
;
147 static BOOL
check_mft_enum(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
148 MFT_REGISTER_TYPE_INFO
*output_type
, const GUID
*expect_class_id
)
150 GUID
*class_ids
= NULL
;
154 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
155 if (FAILED(hr
) || count
== 0)
158 win_skip("MFTEnum returned %#lx, count %u, skipping tests.\n", hr
, count
);
162 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
163 for (i
= 0; i
< count
; ++i
)
164 if (IsEqualGUID(expect_class_id
, class_ids
+ i
))
166 ok(i
< count
, "Failed to find transform.\n");
167 CoTaskMemFree(class_ids
);
172 static void check_mft_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
174 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
175 UINT32 input_count
= 0, output_count
= 0, i
;
179 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
180 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
181 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
183 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
185 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect
->major_type
),
186 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
187 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect
->inputs
[i
].subtype
),
188 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
190 for (; expect
->inputs
[i
].subtype
; ++i
)
191 ok(broken(expect
->inputs
[i
].broken
), "missing input[%u] subtype %s\n",
192 i
, debugstr_guid(expect
->inputs
[i
].subtype
));
193 for (; i
< input_count
; ++i
)
194 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
196 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
198 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect
->major_type
),
199 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
200 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect
->outputs
[i
].subtype
),
201 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
203 for (; expect
->outputs
[i
].subtype
; ++i
)
204 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
205 for (; i
< output_count
; ++i
)
206 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
208 CoTaskMemFree(output_types
);
209 CoTaskMemFree(input_types
);
213 static void check_dmo_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
215 DWORD input_count
= 0, output_count
= 0;
216 DMO_PARTIAL_MEDIATYPE output
[32] = {{{0}}};
217 DMO_PARTIAL_MEDIATYPE input
[32] = {{{0}}};
222 hr
= DMOGetName(class_id
, name
);
223 ok(hr
== S_OK
, "DMOGetName returned %#lx\n", hr
);
224 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
226 hr
= DMOGetTypes(class_id
, ARRAY_SIZE(input
), &input_count
, input
,
227 ARRAY_SIZE(output
), &output_count
, output
);
228 ok(hr
== S_OK
, "DMOGetTypes returned %#lx\n", hr
);
230 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
232 ok(IsEqualGUID(&input
[i
].type
, expect
->major_type
),
233 "got input[%u] major %s\n", i
, debugstr_guid(&input
[i
].type
));
234 ok(IsEqualGUID(&input
[i
].subtype
, expect
->inputs
[i
].subtype
),
235 "got input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
237 for (; expect
->inputs
[i
].subtype
; ++i
)
238 ok(0, "missing input[%u] subtype %s\n", i
, debugstr_guid(expect
->inputs
[i
].subtype
));
239 for (; i
< input_count
; ++i
)
240 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
242 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
244 ok(IsEqualGUID(&output
[i
].type
, expect
->major_type
),
245 "got output[%u] major %s\n", i
, debugstr_guid(&output
[i
].type
));
246 ok(IsEqualGUID(&output
[i
].subtype
, expect
->outputs
[i
].subtype
),
247 "got output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
249 for (; expect
->outputs
[i
].subtype
; ++i
)
250 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
251 for (; i
< output_count
; ++i
)
252 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
255 void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
260 hr
= IMFMediaType_DeleteAllItems(mediatype
);
261 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
263 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
265 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
266 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
270 static void check_mft_optional_methods(IMFTransform
*transform
)
272 DWORD in_id
, out_id
, in_count
, out_count
, in_min
, in_max
, out_min
, out_max
;
273 PROPVARIANT propvar
= {.vt
= VT_EMPTY
};
274 IMFMediaEvent
*event
;
277 in_min
= in_max
= out_min
= out_max
= 0xdeadbeef;
278 hr
= IMFTransform_GetStreamLimits(transform
, &in_min
, &in_max
, &out_min
, &out_max
);
279 ok(hr
== S_OK
, "GetStreamLimits returned %#lx\n", hr
);
280 ok(in_min
== 1, "got input_min %lu\n", in_min
);
281 ok(in_max
== 1, "got input_max %lu\n", in_max
);
282 ok(out_min
== 1, "got output_min %lu\n", out_min
);
283 ok(out_max
== 1, "got output_max %lu\n", out_max
);
285 in_count
= out_count
= 0xdeadbeef;
286 hr
= IMFTransform_GetStreamCount(transform
, &in_count
, &out_count
);
287 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
288 ok(in_count
== 1, "got input_count %lu\n", in_count
);
289 ok(out_count
== 1, "got output_count %lu\n", out_count
);
291 in_count
= out_count
= 1;
292 in_id
= out_id
= 0xdeadbeef;
293 hr
= IMFTransform_GetStreamIDs(transform
, in_count
, &in_id
, out_count
, &out_id
);
294 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
296 hr
= IMFTransform_DeleteInputStream(transform
, 0);
297 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
298 hr
= IMFTransform_DeleteInputStream(transform
, 1);
299 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
301 hr
= IMFTransform_AddInputStreams(transform
, 0, NULL
);
302 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
304 hr
= IMFTransform_AddInputStreams(transform
, 1, &in_id
);
305 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
307 hr
= IMFTransform_SetOutputBounds(transform
, 0, 0);
308 ok(hr
== E_NOTIMPL
|| hr
== S_OK
, "SetOutputBounds returned %#lx\n", hr
);
310 hr
= MFCreateMediaEvent(MEEndOfStream
, &GUID_NULL
, S_OK
, &propvar
, &event
);
311 ok(hr
== S_OK
, "MFCreateMediaEvent returned %#lx\n", hr
);
312 hr
= IMFTransform_ProcessEvent(transform
, 0, NULL
);
313 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
|| hr
== E_INVALIDARG
, "ProcessEvent returned %#lx\n", hr
);
314 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
315 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
316 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
317 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
318 IMFMediaEvent_Release(event
);
321 static void check_mft_get_attributes(IMFTransform
*transform
, const struct attribute_desc
*expect_transform_attributes
,
322 BOOL expect_output_attributes
)
324 IMFAttributes
*attributes
, *tmp_attributes
;
329 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
330 ok(hr
== (expect_transform_attributes
? S_OK
: E_NOTIMPL
), "GetAttributes returned %#lx\n", hr
);
333 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
334 check_attributes(attributes
, expect_transform_attributes
, -1);
336 hr
= IMFTransform_GetAttributes(transform
, &tmp_attributes
);
337 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
338 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
339 IMFAttributes_Release(tmp_attributes
);
341 ref
= IMFAttributes_Release(attributes
);
342 ok(ref
== 1, "Release returned %lu\n", ref
);
345 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
346 ok(hr
== (expect_output_attributes
? S_OK
: E_NOTIMPL
)
347 || broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
348 "GetOutputStreamAttributes returned %#lx\n", hr
);
351 ok(hr
== S_OK
, "GetOutputStreamAttributes returned %#lx\n", hr
);
354 hr
= IMFAttributes_GetCount(attributes
, &count
);
355 ok(hr
== S_OK
, "GetCount returned %#lx\n", hr
);
356 ok(!count
, "got %u attributes\n", count
);
358 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &tmp_attributes
);
359 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
360 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
361 IMFAttributes_Release(tmp_attributes
);
363 ref
= IMFAttributes_Release(attributes
);
364 ok(ref
== 1, "Release returned %lu\n", ref
);
366 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, NULL
);
367 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
368 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 1, &attributes
);
369 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
372 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
373 ok(hr
== E_NOTIMPL
|| broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
374 "GetInputStreamAttributes returned %#lx\n", hr
);
377 #define check_mft_input_stream_info(a, b) check_mft_input_stream_info_(__LINE__, a, b)
378 static void check_mft_input_stream_info_(int line
, MFT_INPUT_STREAM_INFO
*value
, const MFT_INPUT_STREAM_INFO
*expect
)
380 check_member_(__FILE__
, line
, *value
, *expect
, "%I64d", hnsMaxLatency
);
381 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
382 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
383 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbMaxLookahead
);
384 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
387 #define check_mft_get_input_stream_info(a, b, c) check_mft_get_input_stream_info_(__LINE__, a, b, c)
388 static void check_mft_get_input_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_INPUT_STREAM_INFO
*expect
)
390 MFT_INPUT_STREAM_INFO info
, empty
= {0};
393 memset(&info
, 0xcd, sizeof(info
));
394 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &info
);
395 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetInputStreamInfo returned %#lx\n", hr
);
396 check_mft_input_stream_info_(line
, &info
, expect
? expect
: &empty
);
399 #define check_mft_output_stream_info(a, b) check_mft_output_stream_info_(__LINE__, a, b)
400 static void check_mft_output_stream_info_(int line
, MFT_OUTPUT_STREAM_INFO
*value
, const MFT_OUTPUT_STREAM_INFO
*expect
)
402 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
403 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
404 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
407 #define check_mft_get_output_stream_info(a, b, c) check_mft_get_output_stream_info_(__LINE__, a, b, c)
408 static void check_mft_get_output_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_OUTPUT_STREAM_INFO
*expect
)
410 MFT_OUTPUT_STREAM_INFO info
, empty
= {0};
413 memset(&info
, 0xcd, sizeof(info
));
414 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
415 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetOutputStreamInfo returned %#lx\n", hr
);
416 check_mft_output_stream_info_(line
, &info
, expect
? expect
: &empty
);
419 #define check_mft_set_input_type_required(a, b) check_mft_set_input_type_required_(__LINE__, a, b)
420 static void check_mft_set_input_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
422 const struct attribute_desc
*attr
;
423 IMFMediaType
*media_type
;
427 hr
= MFCreateMediaType(&media_type
);
428 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
429 init_media_type(media_type
, attributes
, -1);
431 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
433 winetest_push_context("%s", debugstr_a(attr
->name
));
434 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
435 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
436 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
437 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetInputType returned %#lx.\n", hr
);
438 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
439 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
440 winetest_pop_context();
443 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
444 ok_(__FILE__
, line
)(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
445 ref
= IMFMediaType_Release(media_type
);
446 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
449 static void check_mft_set_input_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
)
451 IMFMediaType
*media_type
;
454 hr
= MFCreateMediaType(&media_type
);
455 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
456 init_media_type(media_type
, attributes
, -1);
458 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
459 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
460 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
461 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
463 IMFMediaType_Release(media_type
);
466 #define check_mft_get_input_current_type(a, b) check_mft_get_input_current_type_(a, b, FALSE, FALSE)
467 static void check_mft_get_input_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
468 BOOL todo_current
, BOOL todo_compare
)
470 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
471 IMFMediaType
*media_type
, *current_type
;
474 hr
= IMFTransform_GetInputCurrentType(transform
, 0, ¤t_type
);
475 todo_wine_if(todo_current
)
476 ok(hr
== expect_hr
, "GetInputCurrentType returned hr %#lx.\n", hr
);
480 hr
= MFCreateMediaType(&media_type
);
481 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
482 init_media_type(media_type
, attributes
, -1);
484 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
485 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
486 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
487 todo_wine_if(todo_compare
)
488 ok(result
, "got result %u.\n", !!result
);
490 IMFMediaType_Release(media_type
);
491 IMFMediaType_Release(current_type
);
494 #define check_mft_set_output_type_required(a, b) check_mft_set_output_type_required_(__LINE__, a, b)
495 static void check_mft_set_output_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
497 const struct attribute_desc
*attr
;
498 IMFMediaType
*media_type
;
502 hr
= MFCreateMediaType(&media_type
);
503 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
504 init_media_type(media_type
, attributes
, -1);
506 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
508 winetest_push_context("%s", debugstr_a(attr
->name
));
509 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
510 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
511 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
512 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetOutputType returned %#lx.\n", hr
);
513 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
514 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
515 winetest_pop_context();
518 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
519 ok_(__FILE__
, line
)(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
520 ref
= IMFMediaType_Release(media_type
);
521 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
524 static void check_mft_set_output_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
527 IMFMediaType
*media_type
;
530 hr
= MFCreateMediaType(&media_type
);
531 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
532 init_media_type(media_type
, attributes
, -1);
534 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
535 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
536 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
537 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
539 IMFMediaType_Release(media_type
);
542 #define check_mft_get_output_current_type(a, b) check_mft_get_output_current_type_(a, b, FALSE, FALSE)
543 static void check_mft_get_output_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
544 BOOL todo_current
, BOOL todo_compare
)
546 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
547 IMFMediaType
*media_type
, *current_type
;
550 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, ¤t_type
);
551 todo_wine_if(todo_current
)
552 ok(hr
== expect_hr
, "GetOutputCurrentType returned hr %#lx.\n", hr
);
556 hr
= MFCreateMediaType(&media_type
);
557 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
558 init_media_type(media_type
, attributes
, -1);
560 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
561 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
562 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
563 todo_wine_if(todo_compare
)
564 ok(result
, "got result %u.\n", !!result
);
566 IMFMediaType_Release(media_type
);
567 IMFMediaType_Release(current_type
);
570 #define check_mft_process_output(a, b, c) check_mft_process_output_(__LINE__, a, b, c)
571 static HRESULT
check_mft_process_output_(int line
, IMFTransform
*transform
, IMFSample
*output_sample
, DWORD
*output_status
)
573 static const DWORD expect_flags
= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
| MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
574 | MFT_OUTPUT_DATA_BUFFER_STREAM_END
| MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
575 MFT_OUTPUT_DATA_BUFFER output
[2];
580 memset(&output
, 0, sizeof(output
));
581 output
[0].pSample
= output_sample
;
582 output
[0].dwStreamID
= 0;
583 ret
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
584 ok_(__FILE__
, line
)(output
[0].dwStreamID
== 0, "got dwStreamID %#lx\n", output
[0].dwStreamID
);
585 ok_(__FILE__
, line
)(output
[0].pEvents
== NULL
, "got pEvents %p\n", output
[0].pEvents
);
586 ok_(__FILE__
, line
)(output
[0].pSample
== output_sample
, "got pSample %p\n", output
[0].pSample
);
587 ok_(__FILE__
, line
)((output
[0].dwStatus
& ~expect_flags
) == 0
588 || broken((output
[0].dwStatus
& ~expect_flags
) == 6) /* Win7 */
589 || broken((output
[0].dwStatus
& ~expect_flags
) == 7) /* Win7 */,
590 "got dwStatus %#lx\n", output
[0].dwStatus
);
591 *output_status
= output
[0].dwStatus
& expect_flags
;
594 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
595 else if (ret
== MF_E_TRANSFORM_STREAM_CHANGE
)
596 ok_(__FILE__
, line
)(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
597 "got status %#lx\n", status
);
600 if (*output_status
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
)
602 hr
= IMFSample_SetUINT32(output_sample
, &mft_output_sample_incomplete
, 1);
603 ok_(__FILE__
, line
)(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
607 hr
= IMFSample_DeleteItem(output_sample
, &mft_output_sample_incomplete
);
608 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
610 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
616 typedef DWORD (*compare_cb
)(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
);
618 static DWORD
compare_nv12(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
620 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
622 /* skip BMP header and RGB data from the dump */
623 size
= *(DWORD
*)(expect
+ 2);
624 *length
= *length
+ size
;
625 expect
= expect
+ size
;
627 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
629 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
630 for (x
= 0; x
< width
; x
++)
632 if (x
< rect
->left
|| x
>= rect
->right
) continue;
633 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
637 for (y
= 0; y
< height
; y
+= 2, data
+= width
, expect
+= width
)
639 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
640 for (x
= 0; x
< width
; x
+= 2)
642 if (x
< rect
->left
|| x
>= rect
->right
) continue;
643 diff
+= abs((int)expect
[x
+ 0] - (int)data
[x
+ 0]);
644 diff
+= abs((int)expect
[x
+ 1] - (int)data
[x
+ 1]);
648 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
649 return diff
* 100 / 256 / size
;
652 static DWORD
compare_i420(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
654 DWORD i
, x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
656 /* skip BMP header and RGB data from the dump */
657 size
= *(DWORD
*)(expect
+ 2);
658 *length
= *length
+ size
;
659 expect
= expect
+ size
;
661 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
663 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
664 for (x
= 0; x
< width
; x
++)
666 if (x
< rect
->left
|| x
>= rect
->right
) continue;
667 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
671 for (i
= 0; i
< 2; ++i
) for (y
= 0; y
< height
; y
+= 2, data
+= width
/ 2, expect
+= width
/ 2)
673 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
674 for (x
= 0; x
< width
; x
+= 2)
676 if (x
< rect
->left
|| x
>= rect
->right
) continue;
677 diff
+= abs((int)expect
[x
/ 2] - (int)data
[x
/ 2]);
681 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
682 return diff
* 100 / 256 / size
;
685 static DWORD
compare_rgb32(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
687 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
689 /* skip BMP header from the dump */
690 size
= *(DWORD
*)(expect
+ 2 + 2 * sizeof(DWORD
));
691 *length
= *length
+ size
;
692 expect
= expect
+ size
;
694 for (y
= 0; y
< height
; y
++, data
+= width
* 4, expect
+= width
* 4)
696 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
697 for (x
= 0; x
< width
; x
++)
699 if (x
< rect
->left
|| x
>= rect
->right
) continue;
700 diff
+= abs((int)expect
[4 * x
+ 0] - (int)data
[4 * x
+ 0]);
701 diff
+= abs((int)expect
[4 * x
+ 1] - (int)data
[4 * x
+ 1]);
702 diff
+= abs((int)expect
[4 * x
+ 2] - (int)data
[4 * x
+ 2]);
706 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3;
707 return diff
* 100 / 256 / size
;
710 static DWORD
compare_pcm16(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
712 const INT16
*data_pcm
= (INT16
*)data
, *expect_pcm
= (INT16
*)expect
;
713 DWORD i
, size
= *length
/ 2, diff
= 0;
715 for (i
= 0; i
< size
; i
++)
716 diff
+= abs((int)*expect_pcm
++ - (int)*data_pcm
++);
718 return diff
* 100 / 65536 / size
;
721 static DWORD
compare_bytes(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
723 DWORD i
, size
= *length
, diff
= 0;
725 for (i
= 0; i
< size
; i
++)
726 diff
+= abs((int)*expect
++ - (int)*data
++);
728 return diff
* 100 / 256 / size
;
731 typedef void (*dump_cb
)(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
);
733 static void dump_rgb32(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
735 DWORD width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
736 static const char magic
[2] = "BM";
742 BITMAPINFOHEADER biHeader
;
745 .length
= length
+ sizeof(header
) + 2, .offset
= sizeof(header
) + 2,
748 .biSize
= sizeof(BITMAPINFOHEADER
), .biWidth
= width
, .biHeight
= height
, .biPlanes
= 1,
749 .biBitCount
= 32, .biCompression
= BI_RGB
, .biSizeImage
= width
* height
* 4,
755 ret
= WriteFile(output
, magic
, sizeof(magic
), &written
, NULL
);
756 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
757 ok(written
== sizeof(magic
), "written %lu bytes\n", written
);
758 ret
= WriteFile(output
, &header
, sizeof(header
), &written
, NULL
);
759 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
760 ok(written
== sizeof(header
), "written %lu bytes\n", written
);
761 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
762 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
763 ok(written
== length
, "written %lu bytes\n", written
);
766 static void dump_nv12(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
768 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
769 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
772 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
774 *rgb32
++ = data
[width
* y
+ x
];
775 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 0];
776 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 1];
780 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
783 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
784 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
785 ok(written
== length
, "written %lu bytes\n", written
);
788 static void dump_i420(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
790 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
791 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
794 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
796 *rgb32
++ = data
[width
* y
+ x
];
797 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + x
/ 2];
798 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + (width
/ 2) * (height
/ 2) + x
/ 2];
802 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
805 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
806 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
807 ok(written
== length
, "written %lu bytes\n", written
);
821 const struct attribute_desc
*attributes
;
822 LONGLONG sample_time
;
823 LONGLONG sample_duration
;
825 const struct buffer_desc
*buffers
;
831 typedef void (*enum_mf_media_buffers_cb
)(IMFMediaBuffer
*buffer
, const struct buffer_desc
*desc
, void *context
);
832 static void enum_mf_media_buffers(IMFSample
*sample
, const struct sample_desc
*sample_desc
,
833 enum_mf_media_buffers_cb callback
, void *context
)
835 IMFMediaBuffer
*buffer
;
839 for (i
= 0; SUCCEEDED(hr
= IMFSample_GetBufferByIndex(sample
, i
, &buffer
)); i
++)
841 winetest_push_context("buffer %lu", i
);
842 ok(hr
== S_OK
, "GetBufferByIndex returned %#lx\n", hr
);
843 ok(i
< sample_desc
->buffer_count
, "got unexpected buffer\n");
845 callback(buffer
, sample_desc
->buffers
+ i
, context
);
847 IMFMediaBuffer_Release(buffer
);
848 winetest_pop_context();
850 ok(hr
== E_INVALIDARG
, "GetBufferByIndex returned %#lx\n", hr
);
853 struct enum_mf_sample_state
855 const struct sample_desc
*next_sample
;
856 struct sample_desc sample
;
859 typedef void (*enum_mf_sample_cb
)(IMFSample
*sample
, const struct sample_desc
*sample_desc
, void *context
);
860 static void enum_mf_samples(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
861 enum_mf_sample_cb callback
, void *context
)
863 struct enum_mf_sample_state state
= {.next_sample
= collection_desc
};
868 for (i
= 0; SUCCEEDED(hr
= IMFCollection_GetElement(samples
, i
, (IUnknown
**)&sample
)); i
++)
870 winetest_push_context("sample %lu", i
);
871 ok(hr
== S_OK
, "GetElement returned %#lx\n", hr
);
873 state
.sample
.sample_time
+= state
.sample
.sample_duration
;
874 if (!state
.sample
.repeat_count
--)
875 state
.sample
= *state
.next_sample
++;
877 callback(sample
, &state
.sample
, context
);
879 IMFSample_Release(sample
);
880 winetest_pop_context();
882 ok(hr
== E_INVALIDARG
, "GetElement returned %#lx\n", hr
);
885 static void dump_mf_media_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*buffer_desc
, HANDLE output
)
887 DWORD length
, written
;
892 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
893 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
895 if (buffer_desc
->dump
)
896 buffer_desc
->dump(data
, length
, &buffer_desc
->rect
, output
);
899 if (buffer_desc
->length
== -1)
901 ret
= WriteFile(output
, &length
, sizeof(length
), &written
, NULL
);
902 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
903 ok(written
== sizeof(length
), "written %lu bytes\n", written
);
906 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
907 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
908 ok(written
== length
, "written %lu bytes\n", written
);
911 hr
= IMFMediaBuffer_Unlock(buffer
);
912 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
915 static void dump_mf_sample(IMFSample
*sample
, const struct sample_desc
*sample_desc
, HANDLE output
)
917 enum_mf_media_buffers(sample
, sample_desc
, dump_mf_media_buffer
, output
);
920 static void dump_mf_sample_collection(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
921 const WCHAR
*output_filename
)
923 WCHAR path
[MAX_PATH
];
926 GetTempPathW(ARRAY_SIZE(path
), path
);
927 lstrcatW(path
, output_filename
);
929 output
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
930 ok(output
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
932 enum_mf_samples(samples
, collection_desc
, dump_mf_sample
, output
);
934 trace("created %s\n", debugstr_w(path
));
938 #define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__LINE__, a, b, c)
939 static DWORD
check_mf_media_buffer_(int line
, IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
,
940 const BYTE
**expect_data
, DWORD
*expect_data_len
)
942 DWORD length
, diff
= 0, expect_length
= expect
->length
;
946 if (expect_length
== -1)
948 expect_length
= *(DWORD
*)*expect_data
;
949 *expect_data
= *expect_data
+ sizeof(DWORD
);
950 *expect_data_len
= *expect_data_len
- sizeof(DWORD
);
953 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
954 ok_(__FILE__
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
955 todo_wine_if(expect
->todo_length
)
956 ok_(__FILE__
, line
)(length
== expect_length
, "got length %#lx\n", length
);
958 if (*expect_data_len
< length
)
959 todo_wine_if(expect
->todo_length
)
960 ok_(__FILE__
, line
)(0, "missing %#lx bytes\n", length
- *expect_data_len
);
961 else if (!expect
->compare
)
962 diff
= compare_bytes(data
, &length
, NULL
, *expect_data
);
964 diff
= expect
->compare(data
, &length
, &expect
->rect
, *expect_data
);
966 hr
= IMFMediaBuffer_Unlock(buffer
);
967 ok_(__FILE__
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
969 *expect_data
= *expect_data
+ min(length
, *expect_data_len
);
970 *expect_data_len
= *expect_data_len
- min(length
, *expect_data_len
);
975 struct check_mf_sample_context
984 static void check_mf_sample_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
, void *context
)
986 struct check_mf_sample_context
*ctx
= context
;
987 DWORD expect_length
= expect
->length
== -1 ? *(DWORD
*)ctx
->data
: expect
->length
;
988 ctx
->diff
+= check_mf_media_buffer_(ctx
->line
, buffer
, expect
, &ctx
->data
, &ctx
->data_len
);
989 ctx
->total_length
+= expect_length
;
992 #define check_mf_sample(a, b, c, d) check_mf_sample_(__LINE__, a, b, c, d)
993 static DWORD
check_mf_sample_(int line
, IMFSample
*sample
, const struct sample_desc
*expect
,
994 const BYTE
**expect_data
, DWORD
*expect_data_len
)
996 struct check_mf_sample_context ctx
= {.data
= *expect_data
, .data_len
= *expect_data_len
, .line
= line
};
997 DWORD buffer_count
, total_length
, sample_flags
;
1001 if (expect
->attributes
)
1002 check_attributes_(line
, (IMFAttributes
*)sample
, expect
->attributes
, -1);
1004 buffer_count
= 0xdeadbeef;
1005 hr
= IMFSample_GetBufferCount(sample
, &buffer_count
);
1006 ok_(__FILE__
, line
)(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
1007 ok_(__FILE__
, line
)(buffer_count
== expect
->buffer_count
,
1008 "got %lu buffers\n", buffer_count
);
1010 sample_flags
= 0xdeadbeef;
1011 hr
= IMFSample_GetSampleFlags(sample
, &sample_flags
);
1012 ok_(__FILE__
, line
)(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
1013 ok_(__FILE__
, line
)(sample_flags
== 0,
1014 "got sample flags %#lx\n", sample_flags
);
1016 timestamp
= 0xdeadbeef;
1017 hr
= IMFSample_GetSampleTime(sample
, ×tamp
);
1018 ok_(__FILE__
, line
)(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
1019 todo_wine_if(expect
->todo_time
&& timestamp
== expect
->todo_time
)
1020 ok_(__FILE__
, line
)(llabs(timestamp
- expect
->sample_time
) <= 50,
1021 "got sample time %I64d\n", timestamp
);
1023 timestamp
= 0xdeadbeef;
1024 hr
= IMFSample_GetSampleDuration(sample
, ×tamp
);
1025 ok_(__FILE__
, line
)(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
1026 todo_wine_if(expect
->todo_length
)
1027 ok_(__FILE__
, line
)(llabs(timestamp
- expect
->sample_duration
) <= 1,
1028 "got sample duration %I64d\n", timestamp
);
1030 enum_mf_media_buffers(sample
, expect
, check_mf_sample_buffer
, &ctx
);
1032 total_length
= 0xdeadbeef;
1033 hr
= IMFSample_GetTotalLength(sample
, &total_length
);
1034 ok_(__FILE__
, line
)(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1035 todo_wine_if(expect
->todo_length
)
1036 ok_(__FILE__
, line
)(total_length
== ctx
.total_length
,
1037 "got total length %#lx\n", total_length
);
1038 ok_(__FILE__
, line
)(*expect_data_len
>= ctx
.total_length
,
1039 "missing %#lx data\n", ctx
.total_length
- *expect_data_len
);
1041 *expect_data
= ctx
.data
;
1042 *expect_data_len
= ctx
.data_len
;
1044 return ctx
.diff
/ buffer_count
;
1047 static void check_mf_sample_collection_enum(IMFSample
*sample
, const struct sample_desc
*expect
, void *context
)
1049 struct check_mf_sample_context
*ctx
= context
;
1050 ctx
->diff
+= check_mf_sample_(ctx
->line
, sample
, expect
, &ctx
->data
, &ctx
->data_len
);
1053 #define check_mf_sample_collection(a, b, c) check_mf_sample_collection_(__LINE__, a, b, c)
1054 static DWORD
check_mf_sample_collection_(int line
, IMFCollection
*samples
,
1055 const struct sample_desc
*expect_samples
, const WCHAR
*expect_data_filename
)
1057 struct check_mf_sample_context ctx
= {.line
= line
};
1061 load_resource(expect_data_filename
, &ctx
.data
, &ctx
.data_len
);
1062 enum_mf_samples(samples
, expect_samples
, check_mf_sample_collection_enum
, &ctx
);
1064 dump_mf_sample_collection(samples
, expect_samples
, expect_data_filename
);
1066 hr
= IMFCollection_GetElementCount(samples
, &count
);
1067 ok_(__FILE__
, line
)(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
1069 return ctx
.diff
/ count
;
1072 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
1074 if (IsEqualIID(riid
, &IID_IUnknown
))
1077 IUnknown_AddRef(iface
);
1082 return E_NOINTERFACE
;
1085 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
1090 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
1095 static const IUnknownVtbl test_unk_vtbl
=
1097 test_unk_QueryInterface
,
1102 static BOOL
is_supported_video_type(const GUID
*guid
)
1104 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
1105 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
1106 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
1107 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
1108 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
1109 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
1110 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
1111 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
1112 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
1113 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
1114 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
1115 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
1116 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
1117 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
1118 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
1119 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
1120 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
1121 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
1122 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
1123 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
1124 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
1125 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
1126 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
1127 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
1128 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
1129 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
1130 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
1131 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
1132 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
1133 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
1134 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
1137 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
1143 hr
= IMFMediaType_GetMajorType(type
, &major
);
1144 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
1146 hr
= IMFMediaType_GetCount(type
, &count
);
1147 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
1148 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
1150 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
1153 static void test_sample_copier(void)
1155 static const struct attribute_desc expect_transform_attributes
[] =
1157 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, 1),
1160 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 16 * 16};
1161 const MFT_INPUT_STREAM_INFO initial_input_info
= {0}, input_info
= {.cbSize
= 16 * 16};
1162 IMFMediaType
*mediatype
, *mediatype2
;
1163 IMFSample
*sample
, *client_sample
;
1164 IMFMediaBuffer
*media_buffer
;
1165 MFT_INPUT_STREAM_INFO info
;
1166 DWORD flags
, output_status
;
1167 IMFTransform
*copier
;
1171 if (!pMFCreateSampleCopierMFT
)
1173 win_skip("MFCreateSampleCopierMFT() is not available.\n");
1177 winetest_push_context("copier");
1179 hr
= pMFCreateSampleCopierMFT(&copier
);
1180 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1182 check_interface(copier
, &IID_IMFTransform
, TRUE
);
1183 check_interface(copier
, &IID_IMediaObject
, FALSE
);
1184 check_interface(copier
, &IID_IPropertyStore
, FALSE
);
1185 check_interface(copier
, &IID_IPropertyBag
, FALSE
);
1187 check_mft_optional_methods(copier
);
1188 check_mft_get_attributes(copier
, expect_transform_attributes
, FALSE
);
1190 /* Available types. */
1191 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
1192 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1193 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1194 IMFMediaType_Release(mediatype
);
1196 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
1197 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1198 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1199 IMFMediaType_Release(mediatype
);
1201 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
1202 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1204 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
1205 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1207 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
1208 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1210 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
1211 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1213 check_mft_get_input_current_type(copier
, NULL
);
1214 check_mft_get_output_current_type(copier
, NULL
);
1216 hr
= MFCreateSample(&sample
);
1217 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1219 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1220 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1222 hr
= MFCreateMediaType(&mediatype
);
1223 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1225 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1226 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
1228 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1229 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1231 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
1232 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1234 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1235 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1237 check_mft_get_input_stream_info(copier
, S_OK
, &initial_input_info
);
1238 check_mft_get_output_stream_info(copier
, S_OK
, &initial_output_info
);
1240 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1241 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1243 memset(&info
, 0xcd, sizeof(info
));
1244 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &info
);
1245 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
1246 check_member(info
, initial_input_info
, "%I64d", hnsMaxLatency
);
1247 check_member(info
, initial_input_info
, "%#lx", dwFlags
);
1249 check_member(info
, initial_input_info
, "%#lx", cbSize
);
1250 check_member(info
, initial_input_info
, "%#lx", cbMaxLookahead
);
1251 check_member(info
, initial_input_info
, "%#lx", cbAlignment
);
1252 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1254 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1255 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1256 IMFMediaType_Release(mediatype2
);
1258 check_mft_get_input_current_type(copier
, NULL
);
1260 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1261 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1263 /* Setting input type resets output type. */
1264 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1265 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1266 IMFMediaType_Release(mediatype2
);
1268 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1269 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1271 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1272 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1274 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
1275 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1276 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
1277 IMFMediaType_Release(mediatype2
);
1279 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1280 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1282 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
1283 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1284 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
1285 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1286 IMFMediaType_Release(mediatype2
);
1288 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1289 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1290 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
1292 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
1293 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1294 IMFMediaType_Release(mediatype2
);
1296 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1297 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1299 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1300 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
1302 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1303 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1304 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1306 /* Pushing samples. */
1307 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1308 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1310 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1311 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1312 IMFMediaBuffer_Release(media_buffer
);
1314 EXPECT_REF(sample
, 1);
1315 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1316 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1317 EXPECT_REF(sample
, 2);
1319 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1320 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1321 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1323 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1324 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1325 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
1327 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1328 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
1330 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1331 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1333 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1334 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1336 hr
= MFCreateSample(&client_sample
);
1337 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1339 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
1340 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1341 IMFMediaBuffer_Release(media_buffer
);
1343 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1344 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1345 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1346 EXPECT_REF(sample
, 1);
1348 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1349 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
1350 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1353 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1354 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1355 EXPECT_REF(sample
, 2);
1357 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
1358 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1360 ref
= IMFSample_Release(sample
);
1361 ok(ref
== 0, "Release returned %ld\n", ref
);
1362 ref
= IMFSample_Release(client_sample
);
1363 ok(ref
== 0, "Release returned %ld\n", ref
);
1365 ref
= IMFTransform_Release(copier
);
1366 ok(ref
== 0, "Release returned %ld\n", ref
);
1367 ref
= IMFMediaType_Release(mediatype
);
1368 ok(ref
== 0, "Release returned %ld\n", ref
);
1370 winetest_pop_context();
1373 struct sample_metadata
1380 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
1381 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
1383 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
1384 IMFSample
*input_sample
, *output_sample
;
1385 DWORD flags
, output_status
;
1390 hr
= MFCreateSample(&input_sample
);
1391 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1395 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
1396 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1398 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
1399 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1401 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
1402 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1405 hr
= MFCreateSample(&output_sample
);
1406 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1408 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
1409 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1411 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
1412 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1414 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
1415 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1417 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
1418 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1420 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
1421 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1423 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
1424 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1426 hr
= check_mft_process_output(copier
, output_sample
, &output_status
);
1427 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1428 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1430 if (!md
) md
= &zero_md
;
1432 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
1433 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1434 ok(md
->flags
== flags
, "Unexpected flags.\n");
1435 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
1436 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1437 ok(md
->time
== time
, "Unexpected time.\n");
1438 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
1439 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1440 ok(md
->duration
== time
, "Unexpected duration.\n");
1442 ref
= IMFSample_Release(input_sample
);
1443 ok(ref
== 0, "Release returned %ld\n", ref
);
1444 ref
= IMFSample_Release(output_sample
);
1445 ok(ref
== 0, "Release returned %ld\n", ref
);
1448 static void test_sample_copier_output_processing(void)
1450 IMFMediaBuffer
*input_buffer
, *output_buffer
;
1451 MFT_OUTPUT_STREAM_INFO output_info
;
1452 struct sample_metadata md
;
1453 IMFMediaType
*mediatype
;
1454 IMFTransform
*copier
;
1460 if (!pMFCreateSampleCopierMFT
)
1463 hr
= pMFCreateSampleCopierMFT(&copier
);
1464 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1466 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
1467 hr
= MFCreateMediaType(&mediatype
);
1468 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1470 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1471 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1473 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
1474 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1476 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1477 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1479 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1480 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1482 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1483 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1485 /* Source and destination are linear buffers, destination is twice as large. */
1486 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
1487 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
1489 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
1490 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1492 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1493 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1494 memset(ptr
, 0xcc, max_length
);
1495 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1496 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1498 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
1499 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1501 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
1502 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1503 memset(ptr
, 0xaa, max_length
);
1504 hr
= IMFMediaBuffer_Unlock(input_buffer
);
1505 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1506 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
1507 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1509 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
1511 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1512 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1513 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
1515 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1516 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1521 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
1523 ref
= IMFMediaBuffer_Release(input_buffer
);
1524 ok(ref
== 0, "Release returned %ld\n", ref
);
1525 ref
= IMFMediaBuffer_Release(output_buffer
);
1526 ok(ref
== 0, "Release returned %ld\n", ref
);
1528 ref
= IMFTransform_Release(copier
);
1529 ok(ref
== 0, "Release returned %ld\n", ref
);
1530 ref
= IMFMediaType_Release(mediatype
);
1531 ok(ref
== 0, "Release returned %ld\n", ref
);
1534 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
1536 IMFMediaBuffer
*media_buffer
;
1543 hr
= MFCreateSample(&sample
);
1544 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
1545 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
1546 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
1547 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
1548 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
1549 ok(length
== 0, "got length %lu\n", length
);
1550 if (!data
) memset(buffer
, 0xcd, size
);
1551 else memcpy(buffer
, data
, size
);
1552 hr
= IMFMediaBuffer_Unlock(media_buffer
);
1553 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
1554 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
1555 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
1556 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1557 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
1558 ret
= IMFMediaBuffer_Release(media_buffer
);
1559 ok(ret
== 1, "Release returned %lu\n", ret
);
1564 static const BYTE aac_codec_data
[14] = {0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x08};
1566 static void test_aac_encoder(void)
1568 const GUID
*const class_id
= &CLSID_AACMFTEncoder
;
1569 const struct transform_info expect_mft_info
=
1571 .name
= L
"Microsoft AAC Audio Encoder MFT",
1572 .major_type
= &MFMediaType_Audio
,
1575 {.subtype
= &MFAudioFormat_PCM
},
1579 {.subtype
= &MFAudioFormat_AAC
},
1583 static const struct attribute_desc input_type_desc
[] =
1585 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1586 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
1587 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
1588 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
1589 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1592 const struct attribute_desc output_type_desc
[] =
1594 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1595 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
1596 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
1597 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
1598 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1599 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000, .required
= TRUE
),
1603 static const struct attribute_desc expect_input_type_desc
[] =
1605 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
1606 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1607 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1608 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1609 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1610 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
1611 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1612 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 2),
1613 ATTR_UINT32(MF_MT_AVG_BITRATE
, 44100 * 2 * 8),
1614 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
1615 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
1616 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
1617 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1620 const struct attribute_desc expect_output_type_desc
[] =
1622 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
1623 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1624 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1625 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1626 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1627 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1628 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1629 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
1630 ATTR_UINT32(MF_MT_AVG_BITRATE
, 96000),
1631 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
1632 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
1633 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1634 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
1635 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
1636 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
)),
1639 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 0x600};
1640 const MFT_INPUT_STREAM_INFO input_info
= {0};
1642 const struct buffer_desc output_buffer_desc
[] =
1644 {.length
= -1 /* variable */},
1646 const struct attribute_desc output_sample_attributes
[] =
1648 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
1651 const struct sample_desc output_sample_desc
[] =
1655 .attributes
= output_sample_attributes
,
1656 .sample_time
= 0, .sample_duration
= 113823,
1657 .buffer_count
= 1, .buffers
= output_buffer_desc
,
1661 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
1662 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
1663 IMFSample
*input_sample
, *output_sample
;
1664 IMFCollection
*output_samples
;
1665 ULONG i
, ret
, audio_data_len
;
1666 DWORD length
, output_status
;
1667 IMFTransform
*transform
;
1668 const BYTE
*audio_data
;
1672 hr
= CoInitialize(NULL
);
1673 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
1675 winetest_push_context("aacenc");
1677 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
1679 check_mft_get_info(class_id
, &expect_mft_info
);
1681 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
1682 &IID_IMFTransform
, (void **)&transform
)))
1685 check_interface(transform
, &IID_IMFTransform
, TRUE
);
1686 check_interface(transform
, &IID_IMediaObject
, FALSE
);
1687 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
1688 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
1690 check_mft_optional_methods(transform
);
1691 check_mft_get_attributes(transform
, NULL
, FALSE
);
1692 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1693 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
1695 check_mft_set_output_type_required(transform
, output_type_desc
);
1696 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
1697 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
1699 check_mft_set_input_type_required(transform
, input_type_desc
);
1700 check_mft_set_input_type(transform
, input_type_desc
);
1701 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
1703 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1704 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
1706 if (!has_video_processor
)
1708 win_skip("Skipping AAC encoder tests on Win7\n");
1712 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
1713 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
1715 input_sample
= create_sample(audio_data
, audio_data_len
);
1716 hr
= IMFSample_SetSampleTime(input_sample
, 0);
1717 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
1718 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
1719 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
1720 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
1721 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
1722 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
1723 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
1724 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
1725 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
1726 ref
= IMFSample_Release(input_sample
);
1727 ok(ref
<= 1, "Release returned %ld\n", ref
);
1729 hr
= MFCreateCollection(&output_samples
);
1730 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
1732 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1733 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
1735 winetest_push_context("%lu", i
);
1736 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
1737 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
1738 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
1739 ref
= IMFSample_Release(output_sample
);
1740 ok(ref
== 1, "Release returned %ld\n", ref
);
1741 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1742 winetest_pop_context();
1744 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
1745 ret
= IMFSample_Release(output_sample
);
1746 ok(ret
== 0, "Release returned %lu\n", ret
);
1747 ok(i
== 88, "got %lu output samples\n", i
);
1749 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacencdata.bin");
1750 ok(ret
== 0, "got %lu%% diff\n", ret
);
1751 IMFCollection_Release(output_samples
);
1753 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1754 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
1755 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
1756 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
1757 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1758 ok(length
== 0, "got length %lu\n", length
);
1759 ret
= IMFSample_Release(output_sample
);
1760 ok(ret
== 0, "Release returned %lu\n", ret
);
1763 ret
= IMFTransform_Release(transform
);
1764 ok(ret
== 0, "Release returned %lu\n", ret
);
1767 winetest_pop_context();
1771 static void test_aac_decoder(void)
1773 const GUID
*const class_id
= &CLSID_MSAACDecMFT
;
1774 const struct transform_info expect_mft_info
=
1776 .name
= L
"Microsoft AAC Audio Decoder MFT",
1777 .major_type
= &MFMediaType_Audio
,
1780 {.subtype
= &MFAudioFormat_AAC
},
1781 {.subtype
= &MFAudioFormat_RAW_AAC1
},
1782 {.subtype
= &MFAudioFormat_ADTS
, .broken
= TRUE
/* <= w8 */},
1786 {.subtype
= &MFAudioFormat_Float
},
1787 {.subtype
= &MFAudioFormat_PCM
},
1791 static const struct attribute_desc expect_input_attributes
[] =
1793 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1794 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1795 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
1796 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 6),
1797 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 24),
1798 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1799 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 1152000),
1802 static const media_type_desc expect_available_inputs
[] =
1805 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1806 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1807 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
1808 /* MF_MT_USER_DATA with some AAC codec data */
1811 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_RAW_AAC1
),
1814 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1815 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1816 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 1),
1817 /* MF_MT_USER_DATA with some AAC codec data */
1820 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1821 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1822 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 3),
1823 /* MF_MT_USER_DATA with some AAC codec data */
1826 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_ADTS
),
1829 static const struct attribute_desc expect_output_attributes
[] =
1831 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1832 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1833 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1834 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1835 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
1838 static const media_type_desc expect_available_outputs
[] =
1841 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1842 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
1843 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
1844 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
1845 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4 * 44100),
1848 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1849 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1850 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1851 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
1852 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * 44100),
1855 const struct attribute_desc expect_transform_attributes
[] =
1857 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, !has_video_processor
/* 1 on W7 */, .todo
= TRUE
),
1858 /* more AAC decoder specific attributes from CODECAPI */
1861 const struct attribute_desc input_type_desc
[] =
1863 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1864 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
1865 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1866 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
), .required
= TRUE
),
1867 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1868 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1869 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
1870 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
1871 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
1874 static const struct attribute_desc output_type_desc
[] =
1876 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1877 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
1878 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
1879 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
1880 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1883 const MFT_OUTPUT_STREAM_INFO output_info
=
1885 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
,
1888 const MFT_INPUT_STREAM_INFO input_info
=
1890 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
1891 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_INPUT_STREAM_HOLDS_BUFFERS
,
1894 const struct buffer_desc output_buffer_desc
[] =
1898 const struct attribute_desc output_sample_attributes
[] =
1900 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
1903 const struct sample_desc output_sample_desc
[] =
1906 .attributes
= output_sample_attributes
+ (has_video_processor
? 0 : 1) /* MFSampleExtension_CleanPoint missing on Win7 */,
1907 .sample_time
= 0, .sample_duration
= 232200,
1908 .buffer_count
= 1, .buffers
= output_buffer_desc
,
1912 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
1913 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
1914 IMFSample
*input_sample
, *output_sample
;
1915 ULONG i
, ret
, ref
, aacenc_data_len
;
1916 IMFCollection
*output_samples
;
1917 DWORD length
, output_status
;
1918 IMFMediaType
*media_type
;
1919 IMFTransform
*transform
;
1920 const BYTE
*aacenc_data
;
1923 hr
= CoInitialize(NULL
);
1924 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
1926 winetest_push_context("aacdec");
1928 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
1930 check_mft_get_info(class_id
, &expect_mft_info
);
1932 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
1933 &IID_IMFTransform
, (void **)&transform
)))
1936 check_interface(transform
, &IID_IMFTransform
, TRUE
);
1937 check_interface(transform
, &IID_IMediaObject
, FALSE
);
1938 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
1939 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
1941 check_mft_optional_methods(transform
);
1942 check_mft_get_attributes(transform
, expect_transform_attributes
, FALSE
);
1943 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1944 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
1946 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
1947 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
1950 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
1952 winetest_push_context("in %lu", i
);
1953 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
1954 check_media_type(media_type
, expect_input_attributes
, -1);
1955 check_media_type(media_type
, expect_available_inputs
[i
], -1);
1956 ret
= IMFMediaType_Release(media_type
);
1957 ok(ret
<= 1, "Release returned %lu\n", ret
);
1958 winetest_pop_context();
1960 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
1961 ok(i
== ARRAY_SIZE(expect_available_inputs
)
1962 || broken(i
== 2) /* w7 */ || broken(i
== 4) /* w8 */,
1963 "%lu input media types\n", i
);
1965 /* setting output media type first doesn't work */
1966 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
1967 check_mft_get_output_current_type(transform
, NULL
);
1969 check_mft_set_input_type_required(transform
, input_type_desc
);
1970 check_mft_set_input_type(transform
, input_type_desc
);
1971 check_mft_get_input_current_type(transform
, input_type_desc
);
1973 /* check new output media types */
1976 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
1978 winetest_push_context("out %lu", i
);
1979 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
1980 check_media_type(media_type
, expect_output_attributes
, -1);
1981 check_media_type(media_type
, expect_available_outputs
[i
], -1);
1982 ret
= IMFMediaType_Release(media_type
);
1983 ok(ret
<= 1, "Release returned %lu\n", ret
);
1984 winetest_pop_context();
1986 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
1987 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
1989 check_mft_set_output_type_required(transform
, output_type_desc
);
1990 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
1991 check_mft_get_output_current_type(transform
, output_type_desc
);
1993 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1994 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
1996 load_resource(L
"aacencdata.bin", &aacenc_data
, &aacenc_data_len
);
1997 ok(aacenc_data_len
== 24861, "got length %lu\n", aacenc_data_len
);
1999 input_sample
= create_sample(aacenc_data
+ sizeof(DWORD
), *(DWORD
*)aacenc_data
);
2000 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2001 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2002 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2003 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2005 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2006 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2008 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2009 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
2010 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2011 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2012 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2014 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2015 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2016 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2017 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2019 hr
= MFCreateCollection(&output_samples
);
2020 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2022 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2023 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2025 winetest_push_context("%lu", i
);
2026 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2027 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2028 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2029 ref
= IMFSample_Release(output_sample
);
2030 ok(ref
== 1, "Release returned %ld\n", ref
);
2031 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2032 winetest_pop_context();
2034 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2035 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2036 ret
= IMFSample_Release(output_sample
);
2037 ok(ret
== 0, "Release returned %lu\n", ret
);
2038 ok(i
== 1, "got %lu output samples\n", i
);
2040 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacdecdata.bin");
2041 ok(ret
== 0, "got %lu%% diff\n", ret
);
2042 IMFCollection_Release(output_samples
);
2044 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2045 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2046 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2047 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2048 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2049 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2050 ok(length
== 0, "got length %lu\n", length
);
2051 ret
= IMFSample_Release(output_sample
);
2052 ok(ret
== 0, "Release returned %lu\n", ret
);
2054 ret
= IMFSample_Release(input_sample
);
2055 ok(ret
== 0, "Release returned %lu\n", ret
);
2056 ret
= IMFTransform_Release(transform
);
2057 ok(ret
== 0, "Release returned %lu\n", ret
);
2060 winetest_pop_context();
2064 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
2065 static const ULONG wmaenc_block_size
= 1487;
2066 static const ULONG wmadec_block_size
= 0x2000;
2068 static void test_wma_encoder(void)
2070 const GUID
*const class_id
= &CLSID_CWMAEncMediaObject
;
2071 const struct transform_info expect_mft_info
=
2073 .name
= L
"WMAudio Encoder MFT",
2074 .major_type
= &MFMediaType_Audio
,
2077 {.subtype
= &MFAudioFormat_PCM
},
2078 {.subtype
= &MFAudioFormat_Float
},
2082 {.subtype
= &MFAudioFormat_WMAudioV8
},
2083 {.subtype
= &MFAudioFormat_WMAudioV9
},
2084 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2087 const struct transform_info expect_dmo_info
=
2089 .name
= L
"WMAudio Encoder DMO",
2090 .major_type
= &MEDIATYPE_Audio
,
2093 {.subtype
= &MEDIASUBTYPE_PCM
},
2097 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2098 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2099 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2103 static const struct attribute_desc input_type_desc
[] =
2105 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2106 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
2107 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2108 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
2109 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2110 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
2111 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
2114 const struct attribute_desc output_type_desc
[] =
2116 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2117 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2118 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2119 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2120 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003, .required
= TRUE
),
2121 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2122 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2125 static const struct attribute_desc expect_input_type_desc
[] =
2127 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2128 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2129 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2130 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2131 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2132 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2133 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
2134 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
2135 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2138 const struct attribute_desc expect_output_type_desc
[] =
2140 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2141 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2142 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2143 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2144 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2145 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2146 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2147 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2150 const MFT_OUTPUT_STREAM_INFO output_info
=
2152 .cbSize
= wmaenc_block_size
,
2155 const MFT_INPUT_STREAM_INFO input_info
=
2157 .hnsMaxLatency
= 19969161,
2162 const struct buffer_desc output_buffer_desc
[] =
2164 {.length
= wmaenc_block_size
},
2166 const struct attribute_desc output_sample_attributes
[] =
2168 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2169 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2172 const struct sample_desc output_sample_desc
[] =
2175 .attributes
= output_sample_attributes
,
2176 .sample_time
= 0, .sample_duration
= 3250794,
2177 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2180 .attributes
= output_sample_attributes
,
2181 .sample_time
= 3250794, .sample_duration
= 3715193,
2182 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2185 .attributes
= output_sample_attributes
,
2186 .sample_time
= 6965986, .sample_duration
= 3366893,
2187 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2191 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2192 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2193 IMFSample
*input_sample
, *output_sample
;
2194 IMFCollection
*output_samples
;
2195 DWORD length
, output_status
;
2196 IMFMediaType
*media_type
;
2197 IMFTransform
*transform
;
2198 const BYTE
*audio_data
;
2199 ULONG audio_data_len
;
2204 hr
= CoInitialize(NULL
);
2205 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2207 winetest_push_context("wmaenc");
2209 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2211 check_mft_get_info(class_id
, &expect_mft_info
);
2212 check_dmo_get_info(class_id
, &expect_dmo_info
);
2214 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2215 &IID_IMFTransform
, (void **)&transform
)))
2218 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2219 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2220 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2221 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2223 check_mft_optional_methods(transform
);
2224 check_mft_get_attributes(transform
, NULL
, FALSE
);
2225 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2226 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2228 check_mft_set_input_type_required(transform
, input_type_desc
);
2230 hr
= MFCreateMediaType(&media_type
);
2231 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
2232 init_media_type(media_type
, input_type_desc
, -1);
2233 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
2234 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
2235 ret
= IMFMediaType_Release(media_type
);
2236 ok(ret
== 0, "Release returned %lu\n", ret
);
2238 check_mft_set_output_type_required(transform
, output_type_desc
);
2239 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2240 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2242 check_mft_set_input_type_required(transform
, input_type_desc
);
2243 check_mft_set_input_type(transform
, input_type_desc
);
2244 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2246 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2247 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2249 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2250 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2252 input_sample
= create_sample(audio_data
, audio_data_len
);
2253 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2254 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2255 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2256 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2257 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2258 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2259 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2260 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2261 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2262 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2263 ref
= IMFSample_Release(input_sample
);
2264 ok(ref
<= 1, "Release returned %ld\n", ref
);
2266 hr
= MFCreateCollection(&output_samples
);
2267 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2269 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2270 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2272 winetest_push_context("%lu", i
);
2273 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2274 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
2275 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2276 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2277 ref
= IMFSample_Release(output_sample
);
2278 ok(ref
== 1, "Release returned %ld\n", ref
);
2279 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2280 winetest_pop_context();
2282 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2283 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2284 ret
= IMFSample_Release(output_sample
);
2285 ok(ret
== 0, "Release returned %lu\n", ret
);
2286 ok(i
== 3, "got %lu output samples\n", i
);
2288 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmaencdata.bin");
2289 ok(ret
== 0, "got %lu%% diff\n", ret
);
2290 IMFCollection_Release(output_samples
);
2292 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2293 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2294 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2295 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2296 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2297 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2298 ok(length
== 0, "got length %lu\n", length
);
2299 ret
= IMFSample_Release(output_sample
);
2300 ok(ret
== 0, "Release returned %lu\n", ret
);
2302 ret
= IMFTransform_Release(transform
);
2303 ok(ret
== 0, "Release returned %lu\n", ret
);
2306 winetest_pop_context();
2310 static void test_wma_decoder(void)
2312 const GUID
*const class_id
= &CLSID_CWMADecMediaObject
;
2313 const struct transform_info expect_mft_info
=
2315 .name
= L
"WMAudio Decoder MFT",
2316 .major_type
= &MFMediaType_Audio
,
2319 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2320 {.subtype
= &MFAudioFormat_WMAudioV8
},
2321 {.subtype
= &MFAudioFormat_WMAudioV9
},
2322 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2326 {.subtype
= &MFAudioFormat_PCM
},
2327 {.subtype
= &MFAudioFormat_Float
},
2330 const struct transform_info expect_dmo_info
=
2332 .name
= L
"WMAudio Decoder DMO",
2333 .major_type
= &MEDIATYPE_Audio
,
2336 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2337 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2338 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2339 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2343 {.subtype
= &MEDIASUBTYPE_PCM
},
2344 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
2348 static const media_type_desc expect_available_inputs
[] =
2351 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2352 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
2353 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2356 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2357 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2358 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2361 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2362 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
2363 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2366 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2367 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
2368 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2371 static const media_type_desc expect_available_outputs
[] =
2374 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2375 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2376 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2377 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2378 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2379 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
2380 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2381 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2382 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2383 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2386 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2387 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2388 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2389 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2390 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2391 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
2392 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2393 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2394 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2395 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2399 const struct attribute_desc input_type_desc
[] =
2401 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2402 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2403 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2404 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2405 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2406 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2407 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003), /* not required by SetInputType, but needed for the transform to work */
2410 static const struct attribute_desc output_type_desc
[] =
2412 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2413 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2414 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2415 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2416 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2417 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
2418 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
2421 const struct attribute_desc expect_input_type_desc
[] =
2423 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2424 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2425 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2426 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2427 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2428 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2429 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2430 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2433 static const struct attribute_desc expect_output_type_desc
[] =
2435 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2436 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2437 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
2438 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2439 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2440 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2441 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2442 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2443 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2446 const MFT_INPUT_STREAM_INFO input_info
=
2448 .cbSize
= wmaenc_block_size
,
2451 const MFT_OUTPUT_STREAM_INFO output_info
=
2453 .cbSize
= wmadec_block_size
,
2457 const struct buffer_desc output_buffer_desc
[] =
2459 {.length
= wmadec_block_size
, .compare
= compare_pcm16
},
2460 {.length
= wmadec_block_size
/ 2, .compare
= compare_pcm16
, .todo_length
= TRUE
},
2462 const struct attribute_desc output_sample_attributes
[] =
2464 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2465 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2468 const struct attribute_desc output_sample_attributes_todo
[] =
2470 ATTR_UINT32(mft_output_sample_incomplete
, 1, .todo
= TRUE
),
2471 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2474 struct sample_desc output_sample_desc
[] =
2477 .attributes
= output_sample_attributes
+ 0,
2478 .sample_time
= 0, .sample_duration
= 928798,
2479 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 1,
2482 .attributes
= output_sample_attributes
+ 0,
2483 .sample_time
= 1857596, .sample_duration
= 928798,
2484 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
2487 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
2488 .sample_time
= 2786394, .sample_duration
= 464399,
2489 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
2493 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2494 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2495 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
2496 IMFSample
*input_sample
, *output_sample
;
2497 IMFCollection
*output_samples
;
2498 DWORD length
, output_status
;
2499 IMediaObject
*media_object
;
2500 IPropertyBag
*property_bag
;
2501 IMFMediaType
*media_type
;
2502 IMFTransform
*transform
;
2503 const BYTE
*wmaenc_data
;
2504 ULONG wmaenc_data_len
;
2508 hr
= CoInitialize(NULL
);
2509 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2511 winetest_push_context("wmadec");
2513 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2515 check_mft_get_info(class_id
, &expect_mft_info
);
2516 check_dmo_get_info(class_id
, &expect_dmo_info
);
2518 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2519 &IID_IMFTransform
, (void **)&transform
)))
2522 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2523 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2525 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2526 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2528 check_mft_optional_methods(transform
);
2529 check_mft_get_attributes(transform
, NULL
, FALSE
);
2530 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2531 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2533 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2534 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2537 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2539 winetest_push_context("in %lu", i
);
2540 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2541 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2542 ret
= IMFMediaType_Release(media_type
);
2543 ok(ret
== 0, "Release returned %lu\n", ret
);
2544 winetest_pop_context();
2547 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
2549 ok(i
== 4, "%lu input media types\n", i
);
2551 /* setting output media type first doesn't work */
2552 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
2553 check_mft_get_output_current_type_(transform
, NULL
, TRUE
, FALSE
);
2555 check_mft_set_input_type_required(transform
, input_type_desc
);
2556 check_mft_set_input_type(transform
, input_type_desc
);
2557 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
2559 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2560 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2562 /* check new output media types */
2565 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
2567 winetest_push_context("out %lu", i
);
2568 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
2569 check_media_type(media_type
, expect_available_outputs
[i
], -1);
2570 ret
= IMFMediaType_Release(media_type
);
2571 ok(ret
== 0, "Release returned %lu\n", ret
);
2572 winetest_pop_context();
2574 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
2575 ok(i
== 2, "%lu output media types\n", i
);
2577 check_mft_set_output_type_required(transform
, output_type_desc
);
2578 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2579 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, TRUE
, FALSE
);
2581 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2582 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2584 load_resource(L
"wmaencdata.bin", &wmaenc_data
, &wmaenc_data_len
);
2585 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
2587 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
2588 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2589 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2590 ret
= IMFSample_Release(input_sample
);
2591 ok(ret
== 0, "Release returned %lu\n", ret
);
2592 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
2593 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2594 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2595 ret
= IMFSample_Release(input_sample
);
2596 ok(ret
== 0, "Release returned %lu\n", ret
);
2597 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2598 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2599 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2600 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2601 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2602 ret
= IMFSample_Release(input_sample
);
2603 ok(ret
== 1, "Release returned %lu\n", ret
);
2605 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2606 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2608 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2609 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2610 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
2611 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
2612 "got output[0].dwStatus %#lx\n", output_status
);
2614 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2615 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2616 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2617 ret
= IMFSample_Release(input_sample
);
2618 ok(ret
== 0, "Release returned %lu\n", ret
);
2620 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2621 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2622 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
2623 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
2624 "got output[0].dwStatus %#lx\n", output_status
);
2626 hr
= MFCreateCollection(&output_samples
);
2627 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2629 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2630 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2632 winetest_push_context("%lu", i
);
2633 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
2634 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2635 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2636 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2637 ref
= IMFSample_Release(output_sample
);
2638 ok(ref
== 1, "Release returned %ld\n", ref
);
2639 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2640 winetest_pop_context();
2642 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2643 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2644 ret
= IMFSample_Release(output_sample
);
2645 ok(ret
== 0, "Release returned %lu\n", ret
);
2646 todo_wine_if(i
== 3) /* wmadec output depends on ffmpeg version used */
2647 ok(i
== 4, "got %lu output samples\n", i
);
2649 if (!strcmp(winetest_platform
, "wine") && i
== 3)
2650 output_sample_desc
[1].attributes
= output_sample_attributes_todo
;
2652 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmadecdata.bin");
2653 todo_wine_if(ret
> 0 && ret
<= 10) /* ffmpeg sometimes offsets the decoded data */
2654 ok(ret
== 0, "got %lu%% diff\n", ret
);
2655 IMFCollection_Release(output_samples
);
2657 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2658 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2659 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2660 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2661 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2662 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2663 ok(length
== 0, "got length %lu\n", length
);
2664 ret
= IMFSample_Release(output_sample
);
2665 ok(ret
== 0, "Release returned %lu\n", ret
);
2667 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2668 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2669 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2671 ret
= IMFTransform_Release(transform
);
2672 ok(ret
== 0, "Release returned %lu\n", ret
);
2673 ret
= IMFSample_Release(input_sample
);
2674 ok(ret
== 0, "Release returned %lu\n", ret
);
2676 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
2677 (void **)&unknown
);
2678 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
2679 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
2680 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2681 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
2682 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2683 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
2684 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2685 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
2686 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2688 ok( unknown
!= &outer
, "got outer IUnknown\n" );
2689 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
2690 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
2691 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
2692 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
2694 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
2695 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
2696 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
2697 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
2698 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
2699 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
2701 ref
= IUnknown_Release( tmp_unknown
);
2702 ok( ref
== 1, "Release returned %lu\n", ref
);
2703 ref
= IPropertyBag_Release( property_bag
);
2704 ok( ref
== 1, "Release returned %lu\n", ref
);
2705 ref
= IMediaObject_Release( media_object
);
2706 ok( ref
== 1, "Release returned %lu\n", ref
);
2707 ref
= IMFTransform_Release( transform
);
2708 ok( ref
== 1, "Release returned %lu\n", ref
);
2709 ref
= IUnknown_Release( unknown
);
2710 ok( ref
== 0, "Release returned %lu\n", ref
);
2713 winetest_pop_context();
2717 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
2718 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
2720 const BYTE
*sample_data
;
2722 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
2723 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
2724 sample_data
= *h264_buf
;
2729 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
2735 return create_sample(sample_data
, *h264_buf
- sample_data
);
2738 static void test_h264_decoder(void)
2740 const GUID
*const class_id
= &CLSID_MSH264DecoderMFT
;
2741 const struct transform_info expect_mft_info
=
2743 .name
= L
"Microsoft H264 Video Decoder MFT",
2744 .major_type
= &MFMediaType_Video
,
2747 {.subtype
= &MFVideoFormat_H264
},
2748 {.subtype
= &MFVideoFormat_H264_ES
},
2752 {.subtype
= &MFVideoFormat_NV12
},
2753 {.subtype
= &MFVideoFormat_YV12
},
2754 {.subtype
= &MFVideoFormat_IYUV
},
2755 {.subtype
= &MFVideoFormat_I420
},
2756 {.subtype
= &MFVideoFormat_YUY2
},
2759 static const media_type_desc default_inputs
[] =
2762 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2763 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
2766 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2767 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
2770 static const struct attribute_desc expect_transform_attributes
[] =
2772 ATTR_UINT32(MF_LOW_LATENCY
, 0),
2773 ATTR_UINT32(MF_SA_D3D_AWARE
, 1, .todo
= TRUE
),
2774 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1, .todo
= TRUE
),
2775 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0, .todo
= TRUE
),
2776 /* more H264 decoder specific attributes from CODECAPI */
2779 static const DWORD input_width
= 120, input_height
= 248;
2780 const media_type_desc default_outputs
[] =
2783 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2784 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
2785 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2786 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2787 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2788 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2789 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2790 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2791 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2792 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2793 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2796 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2797 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
2798 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2799 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2800 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2801 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2802 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2803 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2804 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2805 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2806 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2809 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2810 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
2811 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2812 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2813 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2814 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2815 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2816 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2817 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2818 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2819 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2822 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2823 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
2824 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2825 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2826 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2827 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2828 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2829 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2830 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2831 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2832 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2835 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2836 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
2837 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2838 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2839 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
* 2),
2840 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2841 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2842 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2843 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2844 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 2),
2845 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2848 const struct attribute_desc input_type_desc
[] =
2850 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
2851 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
, .required
= TRUE
),
2852 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2855 const struct attribute_desc output_type_desc
[] =
2857 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
2858 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
2859 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
, .required
= TRUE
),
2860 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2861 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
2862 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
2863 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
2864 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
2867 const struct attribute_desc expect_input_type_desc
[] =
2869 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2870 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
2871 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2872 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 0),
2873 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 0),
2874 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
2875 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
2876 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
2879 const struct attribute_desc expect_output_type_desc
[] =
2881 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2882 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
2883 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2884 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2885 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
2886 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
2887 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
2888 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
2889 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
2890 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
2893 static const struct attribute_desc new_output_type_desc
[] =
2895 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2896 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
2897 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
2898 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
2899 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
2902 static const struct attribute_desc expect_new_output_type_desc
[] =
2904 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2905 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
2906 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
2907 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
2908 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
2909 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
2910 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
2913 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
2914 static const DWORD actual_width
= 96, actual_height
= 96;
2915 const media_type_desc actual_outputs
[] =
2918 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2919 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
2920 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2921 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2922 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
2923 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
2924 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
2925 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2926 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2927 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2928 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2929 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
2932 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2933 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
2934 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2935 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2936 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
2937 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
2938 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
2939 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2940 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2941 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2942 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2943 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
2946 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2947 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
2948 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2949 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2950 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
2951 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
2952 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
2953 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2954 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2955 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2956 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2957 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
2960 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2961 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
2962 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2963 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2964 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
2965 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
2966 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
2967 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2968 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2969 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2970 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2971 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
2974 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2975 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
2976 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2977 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
2978 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
2979 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
2980 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
2981 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2982 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2983 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2984 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2985 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
2988 const MFT_OUTPUT_STREAM_INFO initial_output_info
=
2990 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
2991 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
2992 .cbSize
= 1920 * 1088 * 2,
2994 const MFT_OUTPUT_STREAM_INFO output_info
=
2996 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
2997 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
2998 .cbSize
= input_width
* input_height
* 2,
3000 const MFT_OUTPUT_STREAM_INFO actual_output_info
=
3002 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3003 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3004 .cbSize
= actual_width
* actual_height
* 2,
3006 const MFT_INPUT_STREAM_INFO input_info
=
3008 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3009 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
,
3013 const struct attribute_desc output_sample_attributes
[] =
3015 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3018 const struct buffer_desc output_buffer_desc_nv12
=
3020 .length
= actual_width
* actual_height
* 3 / 2,
3021 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
3023 const struct sample_desc output_sample_desc_nv12
=
3025 .attributes
= output_sample_attributes
,
3026 .sample_time
= 0, .sample_duration
= 333667,
3027 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
3029 const struct buffer_desc output_buffer_desc_i420
=
3031 .length
= actual_width
* actual_height
* 3 / 2,
3032 .compare
= compare_i420
, .dump
= dump_i420
, .rect
= {.right
= 82, .bottom
= 84},
3034 const struct sample_desc expect_output_sample_i420
=
3036 .attributes
= output_sample_attributes
,
3037 .sample_time
= 333667, .sample_duration
= 333667, .todo_time
= 1334666 /* with VA-API */,
3038 .buffer_count
= 1, .buffers
= &output_buffer_desc_i420
,
3041 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
3042 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3043 IMFSample
*input_sample
, *output_sample
;
3044 const BYTE
*h264_encoded_data
;
3045 IMFCollection
*output_samples
;
3046 ULONG h264_encoded_data_len
;
3047 DWORD length
, output_status
;
3048 IMFAttributes
*attributes
;
3049 IMFMediaType
*media_type
;
3050 IMFTransform
*transform
;
3054 hr
= CoInitialize(NULL
);
3055 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3057 winetest_push_context("h264dec");
3059 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
3061 check_mft_get_info(class_id
, &expect_mft_info
);
3063 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3064 &IID_IMFTransform
, (void **)&transform
)))
3067 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3068 check_interface(transform
, &IID_IMediaObject
, FALSE
);
3069 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
3070 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
3072 check_mft_optional_methods(transform
);
3073 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
3074 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3075 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
3077 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3078 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
3079 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
3080 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
3081 IMFAttributes_Release(attributes
);
3083 /* no output type is available before an input type is set */
3085 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3086 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3088 /* setting output media type first doesn't work */
3089 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3090 check_mft_get_output_current_type(transform
, NULL
);
3092 /* check available input types */
3095 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3097 winetest_push_context("in %lu", i
);
3098 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3099 check_media_type(media_type
, default_inputs
[i
], -1);
3100 ret
= IMFMediaType_Release(media_type
);
3101 ok(ret
== 0, "Release returned %lu\n", ret
);
3102 winetest_pop_context();
3104 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3105 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
3107 check_mft_set_input_type_required(transform
, input_type_desc
);
3108 check_mft_set_input_type(transform
, input_type_desc
);
3109 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3111 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3112 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3114 /* output types can now be enumerated (though they are actually the same for all input types) */
3117 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3119 winetest_push_context("out %lu", i
);
3120 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3121 check_media_type(media_type
, default_outputs
[i
], -1);
3122 ret
= IMFMediaType_Release(media_type
);
3123 ok(ret
== 0, "Release returned %lu\n", ret
);
3124 winetest_pop_context();
3126 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3127 ok(i
== 5, "%lu output media types\n", i
);
3129 check_mft_set_output_type_required(transform
, output_type_desc
);
3130 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3131 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3133 /* check that the output media type we've selected don't change the enumeration */
3136 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3138 winetest_push_context("out %lu", i
);
3139 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3140 check_media_type(media_type
, default_outputs
[i
], -1);
3141 ret
= IMFMediaType_Release(media_type
);
3142 ok(ret
== 0, "Release returned %lu\n", ret
);
3143 winetest_pop_context();
3145 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3146 ok(i
== 5, "%lu output media types\n", i
);
3148 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3149 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3151 load_resource(L
"h264data.bin", &h264_encoded_data
, &h264_encoded_data_len
);
3153 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3154 * IMFTransform_ProcessOutput needs a sample or returns an error */
3156 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3157 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3158 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3161 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3164 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3165 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3166 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
3168 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3169 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3170 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3171 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3172 ok(length
== 0, "got length %lu\n", length
);
3173 ret
= IMFSample_Release(output_sample
);
3174 ok(ret
== 0, "Release returned %lu\n", ret
);
3176 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3177 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3178 ret
= IMFSample_Release(input_sample
);
3179 ok(ret
<= 1, "Release returned %lu\n", ret
);
3180 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3182 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3183 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3184 ret
= IMFSample_Release(input_sample
);
3185 ok(ret
<= 1, "Release returned %lu\n", ret
);
3186 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3189 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3190 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3193 ok(i
== 2, "got %lu iterations\n", i
);
3195 ok(h264_encoded_data_len
== 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
3196 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3197 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3198 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3199 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3200 ok(length
== 0, "got length %lu\n", length
);
3201 ret
= IMFSample_Release(output_sample
);
3202 ok(ret
== 0, "Release returned %lu\n", ret
);
3204 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3205 check_mft_get_output_stream_info(transform
, S_OK
, &actual_output_info
);
3208 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3210 winetest_push_context("out %lu", i
);
3211 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3212 check_media_type(media_type
, actual_outputs
[i
], -1);
3213 ret
= IMFMediaType_Release(media_type
);
3214 ok(ret
== 0, "Release returned %lu\n", ret
);
3215 winetest_pop_context();
3217 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3218 ok(i
== 5, "%lu output media types\n", i
);
3220 /* current output type is still the one we selected */
3221 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3223 hr
= MFCreateCollection(&output_samples
);
3224 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3226 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3227 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3228 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3229 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3230 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3231 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3232 ref
= IMFSample_Release(output_sample
);
3233 ok(ref
== 1, "Release returned %ld\n", ref
);
3235 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
3236 ok(ret
== 0, "got %lu%% diff\n", ret
);
3237 IMFCollection_Release(output_samples
);
3239 /* we can change it, but only with the correct frame size */
3240 hr
= MFCreateMediaType(&media_type
);
3241 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
3242 init_media_type(media_type
, output_type_desc
, -1);
3243 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3244 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
3245 init_media_type(media_type
, new_output_type_desc
, -1);
3246 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3247 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
3248 ret
= IMFMediaType_Release(media_type
);
3249 ok(ret
== 1, "Release returned %lu\n", ret
);
3251 check_mft_get_output_current_type_(transform
, expect_new_output_type_desc
, FALSE
, TRUE
);
3253 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3254 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3256 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3258 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3260 while (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
3262 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3263 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3264 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3265 ret
= IMFSample_Release(input_sample
);
3266 ok(ret
<= 1, "Release returned %lu\n", ret
);
3267 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3268 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3271 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3272 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3274 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3275 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3276 ok(length
== 0, "got length %lu\n", length
);
3277 ret
= IMFSample_Release(output_sample
);
3278 ok(ret
== 0, "Release returned %lu\n", ret
);
3280 hr
= MFCreateCollection(&output_samples
);
3281 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3283 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3284 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3285 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3286 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3287 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3288 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3289 ref
= IMFSample_Release(output_sample
);
3290 ok(ref
== 1, "Release returned %ld\n", ref
);
3292 ret
= check_mf_sample_collection(output_samples
, &expect_output_sample_i420
, L
"i420frame.bmp");
3293 ok(ret
== 0, "got %lu%% diff\n", ret
);
3294 IMFCollection_Release(output_samples
);
3296 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3297 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3298 todo_wine_if(hr
== S_OK
) /* when VA-API plugin is used */
3299 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3300 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3301 ret
= IMFSample_Release(output_sample
);
3302 ok(ret
== 0, "Release returned %lu\n", ret
);
3304 ret
= IMFTransform_Release(transform
);
3305 ok(ret
== 0, "Release returned %lu\n", ret
);
3306 ret
= IMFSample_Release(input_sample
);
3307 ok(ret
== 0, "Release returned %lu\n", ret
);
3310 winetest_pop_context();
3314 static void test_audio_convert(void)
3316 const GUID
*const class_id
= &CLSID_CResamplerMediaObject
;
3317 const struct transform_info expect_mft_info
=
3319 .name
= L
"Resampler MFT",
3320 .major_type
= &MFMediaType_Audio
,
3323 {.subtype
= &MFAudioFormat_PCM
},
3324 {.subtype
= &MFAudioFormat_Float
},
3328 {.subtype
= &MFAudioFormat_PCM
},
3329 {.subtype
= &MFAudioFormat_Float
},
3332 const struct transform_info expect_dmo_info
=
3334 .name
= L
"Resampler DMO",
3335 .major_type
= &MEDIATYPE_Audio
,
3338 {.subtype
= &MEDIASUBTYPE_PCM
},
3339 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3343 {.subtype
= &MEDIASUBTYPE_PCM
},
3344 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3348 static const media_type_desc expect_available_inputs
[] =
3351 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3352 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3353 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3356 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3357 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3358 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3361 static const media_type_desc expect_available_outputs
[] =
3364 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3365 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3366 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3369 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3370 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3371 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3374 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3375 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3376 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3377 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3378 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3379 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
3380 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3381 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3382 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3385 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3386 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3387 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3388 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3389 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3390 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
3391 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3392 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3393 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3397 static const struct attribute_desc input_type_desc
[] =
3399 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3400 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
3401 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3402 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
3403 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
3404 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
3405 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
3408 const struct attribute_desc output_type_desc
[] =
3410 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3411 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
3412 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3413 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
3414 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
3415 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
3416 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 44100, .required
= TRUE
),
3419 static const struct attribute_desc expect_input_type_desc
[] =
3421 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3422 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3423 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3424 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3425 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3426 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3427 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
3428 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3429 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
3432 const struct attribute_desc expect_output_type_desc
[] =
3434 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3435 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3436 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3437 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3438 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
3439 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3440 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 4),
3441 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3442 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3445 const MFT_OUTPUT_STREAM_INFO output_info
=
3450 const MFT_INPUT_STREAM_INFO input_info
=
3456 static const ULONG audioconv_block_size
= 0x4000;
3457 const struct buffer_desc output_buffer_desc
[] =
3459 {.length
= audioconv_block_size
, .compare
= compare_pcm16
},
3460 {.length
= 0x3dd8, .compare
= compare_pcm16
, .todo_length
= TRUE
},
3461 {.length
= 0xfc, .compare
= compare_pcm16
},
3463 const struct attribute_desc output_sample_attributes
[] =
3465 ATTR_UINT32(mft_output_sample_incomplete
, 1),
3466 ATTR_UINT32(MFSampleExtension_CleanPoint
, has_video_processor
/* 0 on Win7 */, .todo
= TRUE
),
3469 const struct sample_desc output_sample_desc
[] =
3472 .attributes
= output_sample_attributes
+ 0,
3473 .sample_time
= 0, .sample_duration
= 928798,
3474 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 9,
3477 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
3478 .sample_time
= 9287980, .sample_duration
= 897506,
3479 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
3482 .attributes
= output_sample_attributes
+ 0,
3483 .sample_time
= 10185486, .sample_duration
= 14286,
3484 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 2,
3488 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
3489 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
3490 IMFSample
*input_sample
, *output_sample
;
3491 IMFCollection
*output_samples
;
3492 DWORD length
, output_status
;
3493 IMFMediaType
*media_type
;
3494 IMFTransform
*transform
;
3495 const BYTE
*audio_data
;
3496 ULONG audio_data_len
;
3500 hr
= CoInitialize(NULL
);
3501 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3503 winetest_push_context("resampler");
3505 if (!check_mft_enum(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, class_id
))
3507 check_mft_get_info(class_id
, &expect_mft_info
);
3508 check_dmo_get_info(class_id
, &expect_dmo_info
);
3510 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3511 &IID_IMFTransform
, (void **)&transform
)))
3514 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3515 check_interface(transform
, &IID_IMediaObject
, TRUE
);
3516 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
3517 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
3518 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
3520 check_mft_optional_methods(transform
);
3521 check_mft_get_attributes(transform
, NULL
, FALSE
);
3522 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3523 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3526 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3528 winetest_push_context("out %lu", i
);
3529 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3530 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3531 ret
= IMFMediaType_Release(media_type
);
3532 ok(ret
== 0, "Release returned %lu\n", ret
);
3533 winetest_pop_context();
3535 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3536 ok(i
== 4, "%lu output media types\n", i
);
3539 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3541 winetest_push_context("in %lu", i
);
3542 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3543 check_media_type(media_type
, expect_available_inputs
[i
], -1);
3544 ret
= IMFMediaType_Release(media_type
);
3545 ok(ret
== 0, "Release returned %lu\n", ret
);
3546 winetest_pop_context();
3548 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3549 ok(i
== 2, "%lu input media types\n", i
);
3551 /* setting output media type first doesn't work */
3552 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3553 check_mft_get_output_current_type(transform
, NULL
);
3555 check_mft_set_input_type_required(transform
, input_type_desc
);
3556 check_mft_set_input_type(transform
, input_type_desc
);
3557 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
3559 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3560 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3562 /* check new output media types */
3565 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3567 winetest_push_context("out %lu", i
);
3568 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3569 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3570 ret
= IMFMediaType_Release(media_type
);
3571 ok(ret
== 0, "Release returned %lu\n", ret
);
3572 winetest_pop_context();
3574 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3575 ok(i
== 4, "%lu output media types\n", i
);
3577 check_mft_set_output_type_required(transform
, output_type_desc
);
3578 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3579 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3581 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3582 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3584 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
3585 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
3587 input_sample
= create_sample(audio_data
, audio_data_len
);
3588 hr
= IMFSample_SetSampleTime(input_sample
, 0);
3589 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
3590 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
3591 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
3592 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3593 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3594 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3595 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3596 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3597 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3598 ret
= IMFSample_Release(input_sample
);
3599 ok(ret
<= 1, "Release returned %ld\n", ret
);
3601 hr
= MFCreateCollection(&output_samples
);
3602 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3604 output_sample
= create_sample(NULL
, audioconv_block_size
);
3605 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
3607 winetest_push_context("%lu", i
);
3608 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3609 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
3610 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3611 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3612 ref
= IMFSample_Release(output_sample
);
3613 ok(ref
== 1, "Release returned %ld\n", ref
);
3614 output_sample
= create_sample(NULL
, audioconv_block_size
);
3615 winetest_pop_context();
3617 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3618 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3619 ret
= IMFSample_Release(output_sample
);
3620 ok(ret
== 0, "Release returned %lu\n", ret
);
3622 ok(i
== 12 || broken(i
== 11) /* Win7 */, "got %lu output samples\n", i
);
3624 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"audioconvdata.bin");
3625 ok(ret
== 0, "got %lu%% diff\n", ret
);
3626 IMFCollection_Release(output_samples
);
3628 output_sample
= create_sample(NULL
, audioconv_block_size
);
3629 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3630 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3631 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3632 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3633 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3634 ok(length
== 0, "got length %lu\n", length
);
3635 ret
= IMFSample_Release(output_sample
);
3636 ok(ret
== 0, "Release returned %lu\n", ret
);
3638 ret
= IMFTransform_Release(transform
);
3639 ok(ret
== 0, "Release returned %lu\n", ret
);
3642 winetest_pop_context();
3646 static void test_wmv_decoder(void)
3648 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
3649 const struct transform_info expect_mft_info
=
3651 .name
= L
"WMVideo Decoder MFT",
3652 .major_type
= &MFMediaType_Video
,
3655 {.subtype
= &MFVideoFormat_WMV1
},
3656 {.subtype
= &MFVideoFormat_WMV2
},
3657 {.subtype
= &MFVideoFormat_WMV3
},
3658 {.subtype
= &MEDIASUBTYPE_WMVP
},
3659 {.subtype
= &MEDIASUBTYPE_WVP2
},
3660 {.subtype
= &MEDIASUBTYPE_WMVR
},
3661 {.subtype
= &MEDIASUBTYPE_WMVA
},
3662 {.subtype
= &MFVideoFormat_WVC1
},
3663 {.subtype
= &MFVideoFormat_VC1S
},
3667 {.subtype
= &MFVideoFormat_YV12
},
3668 {.subtype
= &MFVideoFormat_YUY2
},
3669 {.subtype
= &MFVideoFormat_UYVY
},
3670 {.subtype
= &MFVideoFormat_YVYU
},
3671 {.subtype
= &MFVideoFormat_NV11
},
3672 {.subtype
= &MFVideoFormat_NV12
},
3673 {.subtype
= &DMOVideoFormat_RGB32
},
3674 {.subtype
= &DMOVideoFormat_RGB24
},
3675 {.subtype
= &DMOVideoFormat_RGB565
},
3676 {.subtype
= &DMOVideoFormat_RGB555
},
3677 {.subtype
= &DMOVideoFormat_RGB8
},
3680 const struct transform_info expect_dmo_info
=
3682 .name
= L
"WMVideo Decoder DMO",
3683 .major_type
= &MEDIATYPE_Video
,
3686 {.subtype
= &MEDIASUBTYPE_WMV1
},
3687 {.subtype
= &MEDIASUBTYPE_WMV2
},
3688 {.subtype
= &MEDIASUBTYPE_WMV3
},
3689 {.subtype
= &MEDIASUBTYPE_WMVA
},
3690 {.subtype
= &MEDIASUBTYPE_WVC1
},
3691 {.subtype
= &MEDIASUBTYPE_WMVP
},
3692 {.subtype
= &MEDIASUBTYPE_WVP2
},
3693 {.subtype
= &MFVideoFormat_VC1S
},
3697 {.subtype
= &MEDIASUBTYPE_YV12
},
3698 {.subtype
= &MEDIASUBTYPE_YUY2
},
3699 {.subtype
= &MEDIASUBTYPE_UYVY
},
3700 {.subtype
= &MEDIASUBTYPE_YVYU
},
3701 {.subtype
= &MEDIASUBTYPE_NV11
},
3702 {.subtype
= &MEDIASUBTYPE_NV12
},
3703 {.subtype
= &MEDIASUBTYPE_RGB32
},
3704 {.subtype
= &MEDIASUBTYPE_RGB24
},
3705 {.subtype
= &MEDIASUBTYPE_RGB565
},
3706 {.subtype
= &MEDIASUBTYPE_RGB555
},
3707 {.subtype
= &MEDIASUBTYPE_RGB8
},
3711 static const struct attribute_desc expect_common_attributes
[] =
3713 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3716 static const media_type_desc expect_available_inputs
[] =
3718 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
)},
3719 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
)},
3720 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVA
)},
3721 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVP
)},
3722 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WVP2
)},
3723 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV_Unknown
)},
3724 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WVC1
)},
3725 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV3
)},
3726 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_VC1S
)},
3728 static const MFVideoArea actual_aperture
= {.Area
={96,96}};
3729 static const DWORD actual_width
= 96, actual_height
= 96;
3730 const struct attribute_desc expect_output_attributes
[] =
3732 ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
3733 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
3734 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3735 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3736 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3737 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 2),
3740 const media_type_desc expect_available_outputs
[] =
3743 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3744 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3745 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3746 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3747 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3750 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3751 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3752 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3753 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3754 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3757 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3758 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3759 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3760 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3761 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3764 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3765 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3766 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3767 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3768 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3771 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3772 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3773 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3774 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3775 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3778 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3779 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
3780 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3781 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3782 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3785 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3786 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
3787 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3788 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3789 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3792 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3793 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
3794 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3795 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3796 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3799 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3800 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
3801 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3802 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
3803 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
3806 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3807 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
3808 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3809 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 3),
3810 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3),
3813 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3814 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
3815 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3816 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3817 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3818 /* ATTR_BLOB(MF_MT_PALETTE, ... with 12 elements), */
3821 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3822 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
3823 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3824 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3825 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3828 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3829 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB8
),
3830 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3831 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3832 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
),
3833 /* ATTR_BLOB(MF_MT_PALETTE, ... with 904 elements), */
3836 const struct attribute_desc expect_attributes
[] =
3838 ATTR_UINT32(MF_LOW_LATENCY
, 0),
3839 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1),
3840 ATTR_UINT32(MF_SA_D3D_AWARE
, 1),
3841 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0),
3842 /* more attributes from CODECAPI */
3845 const struct attribute_desc input_type_desc
[] =
3847 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3848 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
3849 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
3852 const struct attribute_desc output_type_desc
[] =
3854 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3855 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
3856 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
3859 const struct attribute_desc expect_input_type_desc
[] =
3861 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3862 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
3863 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3864 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3867 const struct attribute_desc expect_output_type_desc
[] =
3869 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3870 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3871 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3872 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3873 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3874 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3875 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
3876 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3877 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3880 const MFT_OUTPUT_STREAM_INFO expect_output_info
=
3882 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
3886 const MFT_OUTPUT_STREAM_INFO empty_output_info
=
3888 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
3890 const MFT_INPUT_STREAM_INFO expect_input_info
=
3896 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3897 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
3898 IMFMediaType
*media_type
;
3899 IMFTransform
*transform
;
3903 hr
= CoInitialize(NULL
);
3904 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3906 winetest_push_context("wmvdec");
3908 if (!has_video_processor
)
3910 win_skip("Skipping inconsistent WMV decoder tests on Win7\n");
3914 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
3916 check_mft_get_info(class_id
, &expect_mft_info
);
3917 check_dmo_get_info(class_id
, &expect_dmo_info
);
3919 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3920 &IID_IMFTransform
, (void **)&transform
)))
3923 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3924 check_interface(transform
, &IID_IMediaObject
, TRUE
);
3925 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
3926 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
3928 check_mft_optional_methods(transform
);
3929 check_mft_get_attributes(transform
, expect_attributes
, TRUE
);
3930 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3931 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
3933 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3935 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3938 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3940 winetest_push_context("in %lu", i
);
3941 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3942 check_media_type(media_type
, expect_common_attributes
, -1);
3943 check_media_type(media_type
, expect_available_inputs
[i
], -1);
3944 ret
= IMFMediaType_Release(media_type
);
3945 ok(!ret
, "Release returned %lu\n", ret
);
3946 winetest_pop_context();
3949 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3951 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
3953 if (hr
== E_NOTIMPL
)
3956 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3957 check_mft_get_output_current_type(transform
, NULL
);
3959 check_mft_set_input_type_required(transform
, input_type_desc
);
3960 check_mft_set_input_type(transform
, input_type_desc
);
3961 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
3964 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3966 winetest_push_context("out %lu", i
);
3967 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3968 check_media_type(media_type
, expect_common_attributes
, -1);
3969 check_media_type(media_type
, expect_output_attributes
, -1);
3970 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3971 ret
= IMFMediaType_Release(media_type
);
3972 ok(!ret
, "Release returned %lu\n", ret
);
3973 winetest_pop_context();
3975 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3976 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
3978 check_mft_set_output_type_required(transform
, output_type_desc
);
3979 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3980 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3982 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
3983 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
3986 ret
= IMFTransform_Release(transform
);
3987 ok(ret
== 0, "Release returned %lu\n", ret
);
3990 winetest_pop_context();
3994 static void test_color_convert(void)
3996 const GUID
*const class_id
= &CLSID_CColorConvertDMO
;
3997 const struct transform_info expect_mft_info
=
3999 .name
= L
"Color Converter MFT",
4000 .major_type
= &MFMediaType_Video
,
4003 {.subtype
= &MFVideoFormat_YV12
},
4004 {.subtype
= &MFVideoFormat_YUY2
},
4005 {.subtype
= &MFVideoFormat_UYVY
},
4006 {.subtype
= &MFVideoFormat_AYUV
},
4007 {.subtype
= &MFVideoFormat_NV12
},
4008 {.subtype
= &DMOVideoFormat_RGB32
},
4009 {.subtype
= &DMOVideoFormat_RGB565
},
4010 {.subtype
= &MFVideoFormat_I420
},
4011 {.subtype
= &MFVideoFormat_IYUV
},
4012 {.subtype
= &MFVideoFormat_YVYU
},
4013 {.subtype
= &DMOVideoFormat_RGB24
},
4014 {.subtype
= &DMOVideoFormat_RGB555
},
4015 {.subtype
= &DMOVideoFormat_RGB8
},
4016 {.subtype
= &MEDIASUBTYPE_V216
},
4017 {.subtype
= &MEDIASUBTYPE_V410
},
4018 {.subtype
= &MFVideoFormat_NV11
},
4019 {.subtype
= &MFVideoFormat_Y41P
},
4020 {.subtype
= &MFVideoFormat_Y41T
},
4021 {.subtype
= &MFVideoFormat_Y42T
},
4022 {.subtype
= &MFVideoFormat_YVU9
},
4026 {.subtype
= &MFVideoFormat_YV12
},
4027 {.subtype
= &MFVideoFormat_YUY2
},
4028 {.subtype
= &MFVideoFormat_UYVY
},
4029 {.subtype
= &MFVideoFormat_AYUV
},
4030 {.subtype
= &MFVideoFormat_NV12
},
4031 {.subtype
= &DMOVideoFormat_RGB32
},
4032 {.subtype
= &DMOVideoFormat_RGB565
},
4033 {.subtype
= &MFVideoFormat_I420
},
4034 {.subtype
= &MFVideoFormat_IYUV
},
4035 {.subtype
= &MFVideoFormat_YVYU
},
4036 {.subtype
= &DMOVideoFormat_RGB24
},
4037 {.subtype
= &DMOVideoFormat_RGB555
},
4038 {.subtype
= &DMOVideoFormat_RGB8
},
4039 {.subtype
= &MEDIASUBTYPE_V216
},
4040 {.subtype
= &MEDIASUBTYPE_V410
},
4041 {.subtype
= &MFVideoFormat_NV11
},
4044 const struct transform_info expect_dmo_info
=
4046 .name
= L
"Color Converter DMO",
4047 .major_type
= &MEDIATYPE_Video
,
4050 {.subtype
= &MEDIASUBTYPE_YV12
},
4051 {.subtype
= &MEDIASUBTYPE_YUY2
},
4052 {.subtype
= &MEDIASUBTYPE_UYVY
},
4053 {.subtype
= &MEDIASUBTYPE_AYUV
},
4054 {.subtype
= &MEDIASUBTYPE_NV12
},
4055 {.subtype
= &MEDIASUBTYPE_RGB32
},
4056 {.subtype
= &MEDIASUBTYPE_RGB565
},
4057 {.subtype
= &MEDIASUBTYPE_I420
},
4058 {.subtype
= &MEDIASUBTYPE_IYUV
},
4059 {.subtype
= &MEDIASUBTYPE_YVYU
},
4060 {.subtype
= &MEDIASUBTYPE_RGB24
},
4061 {.subtype
= &MEDIASUBTYPE_RGB555
},
4062 {.subtype
= &MEDIASUBTYPE_RGB8
},
4063 {.subtype
= &MEDIASUBTYPE_V216
},
4064 {.subtype
= &MEDIASUBTYPE_V410
},
4065 {.subtype
= &MEDIASUBTYPE_NV11
},
4066 {.subtype
= &MEDIASUBTYPE_Y41P
},
4067 {.subtype
= &MEDIASUBTYPE_Y41T
},
4068 {.subtype
= &MEDIASUBTYPE_Y42T
},
4069 {.subtype
= &MEDIASUBTYPE_YVU9
},
4073 {.subtype
= &MEDIASUBTYPE_YV12
},
4074 {.subtype
= &MEDIASUBTYPE_YUY2
},
4075 {.subtype
= &MEDIASUBTYPE_UYVY
},
4076 {.subtype
= &MEDIASUBTYPE_AYUV
},
4077 {.subtype
= &MEDIASUBTYPE_NV12
},
4078 {.subtype
= &MEDIASUBTYPE_RGB32
},
4079 {.subtype
= &MEDIASUBTYPE_RGB565
},
4080 {.subtype
= &MEDIASUBTYPE_I420
},
4081 {.subtype
= &MEDIASUBTYPE_IYUV
},
4082 {.subtype
= &MEDIASUBTYPE_YVYU
},
4083 {.subtype
= &MEDIASUBTYPE_RGB24
},
4084 {.subtype
= &MEDIASUBTYPE_RGB555
},
4085 {.subtype
= &MEDIASUBTYPE_RGB8
},
4086 {.subtype
= &MEDIASUBTYPE_V216
},
4087 {.subtype
= &MEDIASUBTYPE_V410
},
4088 {.subtype
= &MEDIASUBTYPE_NV11
},
4092 static const media_type_desc expect_available_inputs
[20] =
4094 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
4095 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
4096 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
4097 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
4098 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
4099 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
4100 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
4101 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
4102 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
4103 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
4104 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
4105 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
4106 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
4107 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
4108 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
4109 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
4110 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
4111 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
4112 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
4113 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
4115 static const media_type_desc expect_available_outputs
[16] =
4117 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
4118 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
4119 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
4120 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
4121 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
4122 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
4123 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
4124 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
4125 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
4126 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
4127 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
4128 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
4129 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
4130 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
4131 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
4132 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
4134 static const media_type_desc expect_available_common
=
4136 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4137 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4138 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4141 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
4142 static const DWORD actual_width
= 96, actual_height
= 96;
4143 const struct attribute_desc input_type_desc
[] =
4145 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4146 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4147 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4148 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
4151 const struct attribute_desc output_type_desc
[] =
4153 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4154 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
4155 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4158 const struct attribute_desc expect_input_type_desc
[] =
4160 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4161 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4162 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
4163 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4164 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4165 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4166 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4167 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4168 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4171 const struct attribute_desc expect_output_type_desc
[] =
4173 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4174 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
4175 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4176 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
4177 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
4178 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4179 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4180 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4183 const MFT_OUTPUT_STREAM_INFO output_info
=
4185 .cbSize
= actual_width
* actual_height
* 4,
4188 const MFT_INPUT_STREAM_INFO input_info
=
4190 .cbSize
= actual_width
* actual_height
* 3 / 2,
4194 const struct buffer_desc output_buffer_desc
=
4196 .length
= actual_width
* actual_height
* 4,
4197 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.right
= 82, .bottom
= 84},
4199 const struct attribute_desc output_sample_attributes
[] =
4201 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0, .todo
= TRUE
),
4204 const struct sample_desc output_sample_desc
=
4206 .attributes
= output_sample_attributes
,
4207 .sample_time
= 0, .sample_duration
= 10000000,
4208 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
4211 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4212 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
4213 IMFSample
*input_sample
, *output_sample
;
4214 IMFCollection
*output_samples
;
4215 DWORD length
, output_status
;
4216 const BYTE
*nv12frame_data
;
4217 ULONG nv12frame_data_len
;
4218 IMFMediaType
*media_type
;
4219 IMFTransform
*transform
;
4223 hr
= CoInitialize(NULL
);
4224 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4226 winetest_push_context("colorconv");
4228 if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, class_id
))
4230 check_mft_get_info(class_id
, &expect_mft_info
);
4231 check_dmo_get_info(class_id
, &expect_dmo_info
);
4233 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4234 &IID_IMFTransform
, (void **)&transform
)))
4237 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4238 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4239 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4241 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
4243 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
4244 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
4246 check_mft_optional_methods(transform
);
4247 check_mft_get_attributes(transform
, NULL
, FALSE
);
4248 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4249 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4252 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4254 winetest_push_context("out %lu", i
);
4255 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4256 check_media_type(media_type
, expect_available_common
, -1);
4257 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4258 ret
= IMFMediaType_Release(media_type
);
4259 ok(ret
== 0, "Release returned %lu\n", ret
);
4260 winetest_pop_context();
4262 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4263 ok(i
== 16, "%lu output media types\n", i
);
4266 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4268 winetest_push_context("in %lu", i
);
4269 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4270 check_media_type(media_type
, expect_available_common
, -1);
4271 check_media_type(media_type
, expect_available_inputs
[i
], -1);
4272 ret
= IMFMediaType_Release(media_type
);
4273 ok(ret
== 0, "Release returned %lu\n", ret
);
4274 winetest_pop_context();
4276 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4277 ok(i
== 20, "%lu input media types\n", i
);
4279 check_mft_set_output_type_required(transform
, output_type_desc
);
4280 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4281 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4283 check_mft_set_input_type_required(transform
, input_type_desc
);
4284 check_mft_set_input_type(transform
, input_type_desc
);
4285 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4287 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4288 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
4290 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
4291 /* skip BMP header and RGB data from the dump */
4292 length
= *(DWORD
*)(nv12frame_data
+ 2);
4293 nv12frame_data_len
= nv12frame_data_len
- length
;
4294 nv12frame_data
= nv12frame_data
+ length
;
4295 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
4297 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
4298 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4299 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4300 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
4301 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4302 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4303 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4304 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4305 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
4306 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4307 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4308 ret
= IMFSample_Release(input_sample
);
4309 ok(ret
<= 1, "Release returned %ld\n", ret
);
4311 hr
= MFCreateCollection(&output_samples
);
4312 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4314 output_sample
= create_sample(NULL
, output_info
.cbSize
);
4315 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4316 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4317 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4318 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4319 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4320 ref
= IMFSample_Release(output_sample
);
4321 ok(ref
== 1, "Release returned %ld\n", ref
);
4323 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame.bmp");
4324 ok(ret
<= 4 /* small and harmless diff in Wine vs Windows */, "got %lu%% diff\n", ret
);
4325 IMFCollection_Release(output_samples
);
4327 output_sample
= create_sample(NULL
, output_info
.cbSize
);
4328 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4329 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4330 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4331 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
4332 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4333 ok(length
== 0, "got length %lu\n", length
);
4334 ret
= IMFSample_Release(output_sample
);
4335 ok(ret
== 0, "Release returned %lu\n", ret
);
4337 ret
= IMFTransform_Release(transform
);
4338 ok(ret
== 0, "Release returned %ld\n", ret
);
4341 winetest_pop_context();
4345 static void test_video_processor(void)
4347 const GUID
*const class_id
= &CLSID_VideoProcessorMFT
;
4348 const struct transform_info expect_mft_info
=
4350 .name
= L
"Microsoft Video Processor MFT",
4351 .major_type
= &MFMediaType_Video
,
4354 {.subtype
= &MFVideoFormat_IYUV
},
4355 {.subtype
= &MFVideoFormat_YV12
},
4356 {.subtype
= &MFVideoFormat_NV12
},
4357 {.subtype
= &MFVideoFormat_YUY2
},
4358 {.subtype
= &MFVideoFormat_ARGB32
},
4359 {.subtype
= &MFVideoFormat_RGB32
},
4360 {.subtype
= &MFVideoFormat_NV11
},
4361 {.subtype
= &MFVideoFormat_AYUV
},
4362 {.subtype
= &MFVideoFormat_UYVY
},
4363 {.subtype
= &MEDIASUBTYPE_P208
},
4364 {.subtype
= &MFVideoFormat_RGB24
},
4365 {.subtype
= &MFVideoFormat_RGB555
},
4366 {.subtype
= &MFVideoFormat_RGB565
},
4367 {.subtype
= &MFVideoFormat_RGB8
},
4368 {.subtype
= &MFVideoFormat_I420
},
4369 {.subtype
= &MFVideoFormat_Y216
},
4370 {.subtype
= &MFVideoFormat_v410
},
4371 {.subtype
= &MFVideoFormat_Y41P
},
4372 {.subtype
= &MFVideoFormat_Y41T
},
4373 {.subtype
= &MFVideoFormat_Y42T
},
4374 {.subtype
= &MFVideoFormat_YVYU
},
4375 {.subtype
= &MFVideoFormat_420O
},
4379 {.subtype
= &MFVideoFormat_IYUV
},
4380 {.subtype
= &MFVideoFormat_YV12
},
4381 {.subtype
= &MFVideoFormat_NV12
},
4382 {.subtype
= &MFVideoFormat_YUY2
},
4383 {.subtype
= &MFVideoFormat_ARGB32
},
4384 {.subtype
= &MFVideoFormat_RGB32
},
4385 {.subtype
= &MFVideoFormat_NV11
},
4386 {.subtype
= &MFVideoFormat_AYUV
},
4387 {.subtype
= &MFVideoFormat_UYVY
},
4388 {.subtype
= &MEDIASUBTYPE_P208
},
4389 {.subtype
= &MFVideoFormat_RGB24
},
4390 {.subtype
= &MFVideoFormat_RGB555
},
4391 {.subtype
= &MFVideoFormat_RGB565
},
4392 {.subtype
= &MFVideoFormat_RGB8
},
4393 {.subtype
= &MFVideoFormat_I420
},
4394 {.subtype
= &MFVideoFormat_Y216
},
4395 {.subtype
= &MFVideoFormat_v410
},
4396 {.subtype
= &MFVideoFormat_Y41P
},
4397 {.subtype
= &MFVideoFormat_Y41T
},
4398 {.subtype
= &MFVideoFormat_Y42T
},
4399 {.subtype
= &MFVideoFormat_YVYU
},
4402 const GUID expect_available_inputs_w8
[] =
4413 MFVideoFormat_ARGB32
,
4414 MFVideoFormat_RGB32
,
4415 MFVideoFormat_RGB24
,
4418 MFVideoFormat_RGB555
,
4419 MFVideoFormat_RGB565
,
4427 const GUID expect_available_inputs_w10
[] =
4443 MFVideoFormat_ARGB32
,
4444 MFVideoFormat_ABGR32
,
4445 MFVideoFormat_RGB32
,
4446 MFVideoFormat_A2R10G10B10
,
4447 MFVideoFormat_A16B16G16R16F
,
4448 MFVideoFormat_RGB24
,
4451 MFVideoFormat_RGB555
,
4452 MFVideoFormat_RGB565
,
4460 const GUID expect_available_outputs
[] =
4462 MFVideoFormat_A2R10G10B10
, /* enumerated with MFVideoFormat_P010 input */
4463 MFVideoFormat_P010
, /* enumerated with MFVideoFormat_A2R10G10B10 input */
4468 MFVideoFormat_RGB24
,
4469 MFVideoFormat_ARGB32
,
4470 MFVideoFormat_RGB32
,
4472 MFVideoFormat_Y216
, /* enumerated with some input formats */
4473 MFVideoFormat_UYVY
, /* enumerated with some input formats */
4474 MFVideoFormat_YVYU
, /* enumerated with some input formats */
4476 MFVideoFormat_RGB555
,
4477 MFVideoFormat_RGB565
,
4478 MFVideoFormat_AYUV
, /* some inputs enumerate MFVideoFormat_AYUV after RGB565 */
4479 MFVideoFormat_NV12
, /* P010 enumerates NV12 after (A)RGB32 formats */
4480 MFVideoFormat_A16B16G16R16F
, /* enumerated with MFVideoFormat_P010 input */
4482 static const media_type_desc expect_available_common
=
4484 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4486 static const struct attribute_desc expect_transform_attributes
[] =
4488 ATTR_UINT32(MFT_SUPPORT_3DVIDEO
, 1, .todo
= TRUE
),
4489 /* ATTR_UINT32(MF_SA_D3D_AWARE, 1), only on W7 */
4493 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
4494 static const DWORD actual_width
= 96, actual_height
= 96;
4495 const struct attribute_desc input_type_desc
[] =
4497 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4498 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4499 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4500 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
4503 const struct attribute_desc output_type_desc
[] =
4505 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4506 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
4507 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4508 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
4511 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0};
4512 const MFT_INPUT_STREAM_INFO initial_input_info
= {0};
4513 MFT_OUTPUT_STREAM_INFO output_info
= {0};
4514 MFT_INPUT_STREAM_INFO input_info
= {0};
4516 const struct buffer_desc output_buffer_desc
=
4518 .length
= actual_width
* actual_height
* 4,
4519 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
4521 const struct attribute_desc output_sample_attributes
[] =
4523 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1, .todo
= TRUE
),
4526 const struct sample_desc output_sample_desc
=
4528 .attributes
= output_sample_attributes
,
4529 .sample_time
= 0, .sample_duration
= 10000000,
4530 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
4533 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4534 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
4535 DWORD i
, j
, k
, flags
, length
, output_status
;
4536 IMFSample
*input_sample
, *output_sample
;
4537 IMFMediaType
*media_type
, *media_type2
;
4538 const GUID
*expect_available_inputs
;
4539 IMFCollection
*output_samples
;
4540 const BYTE
*nv12frame_data
;
4541 ULONG nv12frame_data_len
;
4542 IMFTransform
*transform
;
4543 IMFMediaBuffer
*buffer
;
4550 hr
= CoInitialize(NULL
);
4551 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4553 winetest_push_context("videoproc");
4555 if (!check_mft_enum(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, class_id
))
4557 check_mft_get_info(class_id
, &expect_mft_info
);
4559 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4560 &IID_IMFTransform
, (void **)&transform
)))
4564 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
4566 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
4567 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
4568 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
4570 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
4571 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4573 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
4574 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4576 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4577 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4579 check_mft_get_input_current_type(transform
, NULL
);
4580 check_mft_get_output_current_type(transform
, NULL
);
4582 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
4583 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
4585 /* Configure stream types. */
4588 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
4590 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
4594 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
4595 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
4596 ok(media_type
!= media_type2
, "Unexpected instance.\n");
4597 ref
= IMFMediaType_Release(media_type2
);
4598 ok(ref
== 0, "Release returned %ld\n", ref
);
4600 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
4601 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
4602 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
4604 hr
= IMFMediaType_GetCount(media_type
, &count
);
4605 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
4606 ok(count
== 2, "Unexpected count %u.\n", count
);
4608 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
4609 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
4610 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
4612 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
4613 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4615 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4616 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
4618 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
4619 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
4621 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
4622 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
4623 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
4624 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
4626 ref
= IMFMediaType_Release(media_type
);
4627 ok(ref
== 0, "Release returned %ld\n", ref
);
4631 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
4632 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4634 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
4635 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
4637 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4638 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
4640 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
4641 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
4642 ok(media_type
!= media_type2
, "Unexpected instance.\n");
4643 IMFMediaType_Release(media_type2
);
4645 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
4646 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
4647 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
4649 input_info
.cbSize
= 0;
4650 if (!IsEqualGUID(&guid
, &MFVideoFormat_P208
) && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y41T
)
4651 && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y42T
))
4653 hr
= MFCalculateImageSize(&guid
, 16, 16, (UINT32
*)&input_info
.cbSize
);
4654 todo_wine_if(IsEqualGUID(&guid
, &MFVideoFormat_NV11
) || IsEqualGUID(&guid
, &MFVideoFormat_YVYU
)
4655 || IsEqualGUID(&guid
, &MFVideoFormat_Y216
) || IsEqualGUID(&guid
, &MFVideoFormat_v410
)
4656 || IsEqualGUID(&guid
, &MFVideoFormat_Y41P
))
4657 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4659 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4660 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
4662 IMFMediaType_Release(media_type
);
4666 hr
= MFCreateMediaType(&media_type
);
4667 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
4669 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
4670 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4672 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
4673 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4675 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
4676 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4678 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4679 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
4681 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
4682 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
4684 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
4685 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
4687 hr
= MFCalculateImageSize(&MFVideoFormat_IYUV
, 16, 16, (UINT32
*)&input_info
.cbSize
);
4688 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4689 hr
= MFCalculateImageSize(&MFVideoFormat_RGB32
, 16, 16, (UINT32
*)&output_info
.cbSize
);
4690 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4691 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4692 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
4694 hr
= MFCreateSample(&input_sample
);
4695 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
4697 hr
= MFCreateSample(&output_sample
);
4698 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
4700 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4702 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
4704 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4706 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
4708 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4710 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
4712 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4714 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
4716 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4717 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
4718 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4720 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
4722 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
4723 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
4725 hr
= IMFSample_AddBuffer(input_sample
, buffer
);
4726 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
4728 hr
= IMFSample_AddBuffer(output_sample
, buffer
);
4729 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
4731 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4733 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
4737 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4738 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
4741 ref
= IMFTransform_Release(transform
);
4742 ok(ref
== 0, "Release returned %ld\n", ref
);
4744 ref
= IMFMediaType_Release(media_type
);
4745 ok(ref
== 0, "Release returned %ld\n", ref
);
4746 ref
= IMFSample_Release(input_sample
);
4747 ok(ref
== 0, "Release returned %ld\n", ref
);
4748 ref
= IMFSample_Release(output_sample
);
4749 ok(ref
== 0, "Release returned %ld\n", ref
);
4750 ref
= IMFMediaBuffer_Release(buffer
);
4751 ok(ref
== 0, "Release returned %ld\n", ref
);
4754 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
4755 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
4757 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4758 check_interface(transform
, &IID_IMediaObject
, FALSE
);
4759 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
4760 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
4762 check_mft_optional_methods(transform
);
4763 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
4764 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
4765 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
4767 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4768 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4770 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 23, &media_type
);
4771 ok(hr
== S_OK
|| hr
== MF_E_NO_MORE_TYPES
/* w8 */, "GetOutputAvailableType returned %#lx\n", hr
);
4772 if (hr
== MF_E_NO_MORE_TYPES
)
4773 expect_available_inputs
= expect_available_inputs_w8
;
4776 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 27, &media_type
);
4777 ok(hr
== S_OK
|| broken(hr
== MF_E_NO_MORE_TYPES
) /* w1064v1507 */, "GetOutputAvailableType returned %#lx\n", hr
);
4778 if (hr
== MF_E_NO_MORE_TYPES
)
4779 expect_available_inputs
= expect_available_inputs_w10
+ 3;
4781 expect_available_inputs
= expect_available_inputs_w10
;
4785 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4787 /* FIXME: Skip exotic input types which aren't directly accepted */
4788 if (IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L8
)
4789 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L16
)
4790 || IsEqualGUID(&expect_available_inputs
[i
], &MFAudioFormat_MPEG
)
4791 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_420O
)
4792 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_A16B16G16R16F
) /* w1064v1507 */)
4795 winetest_push_context("in %lu", i
);
4796 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4797 check_media_type(media_type
, expect_available_common
, -1);
4799 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
4800 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
4802 /* w1064v1507 doesn't expose MFVideoFormat_ABGR32 input */
4803 if (broken(IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_ABGR32
)
4804 && IsEqualGUID(&guid
, &MFVideoFormat_RGB32
)))
4805 expect_available_inputs
++;
4807 ok(IsEqualGUID(&expect_available_inputs
[i
], &guid
), "got subtype %s\n", debugstr_guid(&guid
));
4809 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4810 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
4812 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)actual_width
<< 32 | actual_height
);
4813 ok(hr
== S_OK
, "SetUINT64 returned %#lx.\n", hr
);
4814 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4815 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
4817 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type2
);
4818 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx.\n", hr
);
4819 hr
= IMFMediaType_IsEqual(media_type
, media_type2
, &flags
);
4820 ok(hr
== S_OK
, "IsEqual returned %#lx.\n", hr
);
4821 IMFMediaType_Release(media_type2
);
4823 ret
= IMFMediaType_Release(media_type
);
4824 ok(ret
== 1, "Release returned %lu\n", ret
);
4827 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++j
, &media_type
)))
4829 winetest_push_context("out %lu", j
);
4830 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4831 check_media_type(media_type
, expect_available_common
, -1);
4833 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
4834 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
4836 for (; k
< ARRAY_SIZE(expect_available_outputs
); k
++)
4837 if (IsEqualGUID(&expect_available_outputs
[k
], &guid
))
4839 ok(k
< ARRAY_SIZE(expect_available_outputs
), "got subtype %s\n", debugstr_guid(&guid
));
4841 ret
= IMFMediaType_Release(media_type
);
4842 ok(ret
== 0, "Release returned %lu\n", ret
);
4843 winetest_pop_context();
4845 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4847 winetest_pop_context();
4849 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4850 ok(i
== 22 || i
== 30 || broken(i
== 26) /* w1064v1507 */, "%lu input media types\n", i
);
4852 check_mft_set_input_type_required(transform
, input_type_desc
);
4853 check_mft_set_input_type(transform
, input_type_desc
);
4854 check_mft_get_input_current_type(transform
, input_type_desc
);
4856 check_mft_set_output_type_required(transform
, output_type_desc
);
4857 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4858 check_mft_get_output_current_type(transform
, output_type_desc
);
4860 input_info
.cbSize
= actual_width
* actual_height
* 3 / 2;
4861 output_info
.cbSize
= actual_width
* actual_height
* 4;
4862 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4863 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
4865 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
4866 /* skip BMP header and RGB data from the dump */
4867 length
= *(DWORD
*)(nv12frame_data
+ 2);
4868 nv12frame_data_len
= nv12frame_data_len
- length
;
4869 nv12frame_data
= nv12frame_data
+ length
;
4870 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
4872 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
4873 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4874 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4875 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
4876 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4877 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4878 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4879 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4880 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
4881 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4882 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4883 ret
= IMFSample_Release(input_sample
);
4884 ok(ret
<= 1, "Release returned %ld\n", ret
);
4886 hr
= MFCreateCollection(&output_samples
);
4887 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4889 output_sample
= create_sample(NULL
, output_info
.cbSize
);
4890 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4891 ok(hr
== S_OK
|| broken(hr
== MF_E_SHUTDOWN
) /* w8 */, "ProcessOutput returned %#lx\n", hr
);
4894 win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n");
4897 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4899 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4900 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4901 ref
= IMFSample_Release(output_sample
);
4902 ok(ref
== 1, "Release returned %ld\n", ref
);
4904 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame-vp.bmp");
4906 ok(ret
== 0 || broken(ret
== 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret
);
4907 IMFCollection_Release(output_samples
);
4909 output_sample
= create_sample(NULL
, output_info
.cbSize
);
4910 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4911 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4912 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4913 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
4914 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4915 ok(length
== 0, "got length %lu\n", length
);
4918 ret
= IMFSample_Release(output_sample
);
4919 ok(ret
== 0, "Release returned %lu\n", ret
);
4921 ret
= IMFTransform_Release(transform
);
4922 ok(ret
== 0, "Release returned %ld\n", ret
);
4925 winetest_pop_context();
4929 static void test_mp3_decoder(void)
4931 const GUID
*const class_id
= &CLSID_CMP3DecMediaObject
;
4932 const struct transform_info expect_mft_info
=
4934 .name
= L
"MP3 Decoder MFT",
4935 .major_type
= &MFMediaType_Audio
,
4938 {.subtype
= &MFAudioFormat_MP3
},
4942 {.subtype
= &MFAudioFormat_PCM
},
4945 const struct transform_info expect_dmo_info
=
4947 .name
= L
"MP3 Decoder DMO",
4948 .major_type
= &MEDIATYPE_Audio
,
4951 {.subtype
= &MFAudioFormat_MP3
},
4955 {.subtype
= &MEDIASUBTYPE_PCM
},
4959 static const ULONG mp3dec_block_size
= 0x1200;
4960 static const media_type_desc expect_available_inputs
[] =
4963 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4964 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
4965 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4968 static const media_type_desc expect_available_outputs
[] =
4971 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4972 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
4973 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
4974 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4975 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
4976 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
4977 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
4978 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4981 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4982 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4983 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
4984 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4985 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
4986 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
4987 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
4988 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4991 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4992 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4993 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
4994 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4995 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
4996 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
4997 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
4998 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5001 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5002 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5003 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
5004 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
5005 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5006 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
5007 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
5008 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5011 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5012 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5013 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
5014 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
5015 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5016 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
5017 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
5018 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5021 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5022 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5023 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
5024 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
5025 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5026 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050),
5027 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
5028 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5032 const struct attribute_desc input_type_desc
[] =
5034 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
5035 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
, .required
= TRUE
),
5036 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
5037 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5040 static const struct attribute_desc output_type_desc
[] =
5042 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
5043 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
5044 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
5045 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
5046 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
5047 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
5048 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
5051 const struct attribute_desc expect_input_type_desc
[] =
5053 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5054 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
5055 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5056 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5057 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
5060 static const struct attribute_desc expect_output_type_desc
[] =
5062 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5063 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5064 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
5065 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5066 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5067 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
5068 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
5069 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5070 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
5073 const MFT_OUTPUT_STREAM_INFO output_info
=
5075 .cbSize
= mp3dec_block_size
,
5078 const MFT_INPUT_STREAM_INFO input_info
=
5083 const struct buffer_desc output_buffer_desc
[] =
5085 {.length
= 0x9c0, .compare
= compare_pcm16
},
5086 {.length
= mp3dec_block_size
, .compare
= compare_pcm16
},
5088 const struct attribute_desc output_sample_attributes
[] =
5090 ATTR_UINT32(mft_output_sample_incomplete
, 1),
5091 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
5094 const struct sample_desc output_sample_desc
[] =
5097 .attributes
= output_sample_attributes
+ 0,
5098 .sample_time
= 0, .sample_duration
= 282993,
5099 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
5102 .attributes
= output_sample_attributes
+ 0,
5103 .sample_time
= 282993, .sample_duration
= 522449,
5104 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 18,
5107 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
5108 .sample_time
= 10209524, .sample_duration
= 522449,
5109 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1,
5113 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
5114 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_MP3
};
5115 IMFSample
*input_sample
, *output_sample
;
5116 IMFCollection
*output_samples
;
5117 DWORD length
, output_status
;
5118 IMFMediaType
*media_type
;
5119 IMFTransform
*transform
;
5120 const BYTE
*mp3enc_data
;
5121 ULONG mp3enc_data_len
;
5125 hr
= CoInitialize(NULL
);
5126 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5128 winetest_push_context("mp3dec");
5130 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
5132 check_mft_get_info(class_id
, &expect_mft_info
);
5133 check_dmo_get_info(class_id
, &expect_dmo_info
);
5135 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5136 &IID_IMFTransform
, (void **)&transform
)))
5139 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5140 check_interface(transform
, &IID_IMediaObject
, TRUE
);
5142 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
5143 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
5145 check_mft_optional_methods(transform
);
5146 check_mft_get_attributes(transform
, NULL
, FALSE
);
5147 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5148 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5150 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5151 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
5154 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5156 winetest_push_context("in %lu", i
);
5157 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5158 check_media_type(media_type
, expect_available_inputs
[i
], -1);
5159 ret
= IMFMediaType_Release(media_type
);
5160 ok(ret
== 0, "Release returned %lu\n", ret
);
5161 winetest_pop_context();
5164 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5166 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
5168 /* setting output media type first doesn't work */
5169 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
5170 check_mft_get_output_current_type(transform
, NULL
);
5172 check_mft_set_input_type_required(transform
, input_type_desc
);
5173 check_mft_set_input_type(transform
, input_type_desc
);
5174 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
5176 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5177 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5179 /* check new output media types */
5182 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
5184 winetest_push_context("out %lu", i
);
5185 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5186 check_media_type(media_type
, expect_available_outputs
[i
], -1);
5187 ret
= IMFMediaType_Release(media_type
);
5188 ok(ret
== 0, "Release returned %lu\n", ret
);
5189 winetest_pop_context();
5191 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5192 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
5194 check_mft_set_output_type_required(transform
, output_type_desc
);
5195 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
5196 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
5198 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5199 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5201 load_resource(L
"mp3encdata.bin", &mp3enc_data
, &mp3enc_data_len
);
5202 ok(mp3enc_data_len
== 6295, "got length %lu\n", mp3enc_data_len
);
5204 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
5205 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5206 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5207 ret
= IMFSample_Release(input_sample
);
5208 ok(ret
== 1, "Release returned %lu\n", ret
);
5210 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
5211 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5212 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5213 ret
= IMFSample_Release(input_sample
);
5214 ok(ret
== 0, "Release returned %lu\n", ret
);
5216 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
5217 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
5219 hr
= MFCreateCollection(&output_samples
);
5220 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
5222 /* first sample is broken */
5223 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5224 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5225 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5226 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
5227 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
5228 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
5229 ok(length
== mp3dec_block_size
/* Win8 */ || length
== 0x9c0 /* Win10 */ || length
== 0x900 /* Win7 */,
5230 "got length %lu\n", length
);
5231 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5232 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5233 ref
= IMFSample_Release(output_sample
);
5234 ok(ref
== 1, "Release returned %ld\n", ref
);
5236 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5237 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
5239 winetest_push_context("%lu", i
);
5240 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5241 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
5242 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5243 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5244 ref
= IMFSample_Release(output_sample
);
5245 ok(ref
== 1, "Release returned %ld\n", ref
);
5246 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5247 winetest_pop_context();
5249 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5250 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5251 ret
= IMFSample_Release(output_sample
);
5252 ok(ret
== 0, "Release returned %lu\n", ret
);
5253 ok(i
== 20 || broken(i
== 41) /* Win7 */, "got %lu output samples\n", i
);
5255 if (broken(length
!= 0x9c0))
5256 win_skip("Skipping MP3 decoder output sample checks on Win7 / Win8\n");
5259 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"mp3decdata.bin");
5260 ok(ret
== 0, "got %lu%% diff\n", ret
);
5262 IMFCollection_Release(output_samples
);
5264 output_sample
= create_sample(NULL
, mp3dec_block_size
);
5265 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5266 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5267 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5268 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
5269 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
5270 ok(length
== 0, "got length %lu\n", length
);
5271 ret
= IMFSample_Release(output_sample
);
5272 ok(ret
== 0, "Release returned %lu\n", ret
);
5274 ret
= IMFTransform_Release(transform
);
5275 ok(ret
== 0, "Release returned %lu\n", ret
);
5278 winetest_pop_context();
5282 START_TEST(transform
)
5286 test_sample_copier();
5287 test_sample_copier_output_processing();
5292 test_h264_decoder();
5294 test_audio_convert();
5295 test_color_convert();
5296 test_video_processor();