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"
41 #include "wine/test.h"
45 DEFINE_GUID(DMOVideoFormat_RGB24
,D3DFMT_R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
46 DEFINE_GUID(DMOVideoFormat_RGB32
,D3DFMT_X8R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
47 DEFINE_GUID(DMOVideoFormat_RGB555
,D3DFMT_X1R5G5B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
48 DEFINE_GUID(DMOVideoFormat_RGB565
,D3DFMT_R5G6B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
49 DEFINE_GUID(DMOVideoFormat_RGB8
,D3DFMT_P8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
50 DEFINE_GUID(MFAudioFormat_RAW_AAC1
,WAVE_FORMAT_RAW_AAC1
,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
51 DEFINE_GUID(MFVideoFormat_ABGR32
,0x00000020,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
52 DEFINE_GUID(MFVideoFormat_P208
,0x38303250,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
53 DEFINE_GUID(MFVideoFormat_VC1S
,0x53314356,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
54 DEFINE_GUID(MFVideoFormat_WMV_Unknown
,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b);
56 DEFINE_GUID(mft_output_sample_incomplete
,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
58 static void load_resource(const WCHAR
*filename
, const BYTE
**data
, DWORD
*length
)
60 HRSRC resource
= FindResourceW(NULL
, filename
, (const WCHAR
*)RT_RCDATA
);
61 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
62 *data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
63 *length
= SizeofResource(GetModuleHandleW(NULL
), resource
);
66 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
67 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
71 refcount
= IUnknown_Release(obj
);
72 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
76 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
77 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
79 IUnknown
*iface
= iface_ptr
;
80 HRESULT hr
, expected_hr
;
83 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
85 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
86 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
88 IUnknown_Release(unk
);
91 #define check_member_(file, line, val, exp, fmt, member) \
92 ok_ (file, line)((val).member == (exp).member, "got " #member " " fmt "\n", (val).member)
93 #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
95 void check_attributes_(const char *file
, int line
, IMFAttributes
*attributes
,
96 const struct attribute_desc
*desc
, ULONG limit
)
98 char buffer
[256], *buf
= buffer
;
103 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
105 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
106 todo_wine_if(desc
[i
].todo
)
107 ok_(file
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
108 if (hr
!= S_OK
) continue;
112 default: sprintf(buffer
, "??"); break;
113 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
114 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
117 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
119 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
121 case VT_VECTOR
| VT_UI1
:
122 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
123 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
124 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
125 if (value
.caub
.cElems
> 16)
126 buf
+= sprintf(buf
, "...}");
128 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
132 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
133 todo_wine_if(desc
[i
].todo_value
)
134 ok_(file
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
135 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
139 struct transform_info
142 const GUID
*major_type
;
147 } inputs
[32], input_end
, outputs
[32], output_end
;
150 static BOOL
check_mft_enum(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
151 MFT_REGISTER_TYPE_INFO
*output_type
, const GUID
*expect_class_id
)
153 GUID
*class_ids
= NULL
;
157 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
158 if (FAILED(hr
) || count
== 0)
161 win_skip("MFTEnum returned %#lx, count %u, skipping tests.\n", hr
, count
);
165 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
166 for (i
= 0; i
< count
; ++i
)
167 if (IsEqualGUID(expect_class_id
, class_ids
+ i
))
169 ok(i
< count
, "Failed to find transform.\n");
170 CoTaskMemFree(class_ids
);
175 static void check_mft_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
177 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
178 UINT32 input_count
= 0, output_count
= 0, i
;
182 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
183 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
184 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
186 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
188 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect
->major_type
),
189 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
190 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect
->inputs
[i
].subtype
),
191 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
193 for (; expect
->inputs
[i
].subtype
; ++i
)
194 ok(broken(expect
->inputs
[i
].broken
), "missing input[%u] subtype %s\n",
195 i
, debugstr_guid(expect
->inputs
[i
].subtype
));
196 for (; i
< input_count
; ++i
)
197 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
199 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
201 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect
->major_type
),
202 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
203 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect
->outputs
[i
].subtype
),
204 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
206 for (; expect
->outputs
[i
].subtype
; ++i
)
207 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
208 for (; i
< output_count
; ++i
)
209 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
211 CoTaskMemFree(output_types
);
212 CoTaskMemFree(input_types
);
216 static void check_dmo_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
218 DWORD input_count
= 0, output_count
= 0;
219 DMO_PARTIAL_MEDIATYPE output
[32] = {{{0}}};
220 DMO_PARTIAL_MEDIATYPE input
[32] = {{{0}}};
225 hr
= DMOGetName(class_id
, name
);
226 ok(hr
== S_OK
, "DMOGetName returned %#lx\n", hr
);
227 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
229 hr
= DMOGetTypes(class_id
, ARRAY_SIZE(input
), &input_count
, input
,
230 ARRAY_SIZE(output
), &output_count
, output
);
231 ok(hr
== S_OK
, "DMOGetTypes returned %#lx\n", hr
);
233 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
235 ok(IsEqualGUID(&input
[i
].type
, expect
->major_type
),
236 "got input[%u] major %s\n", i
, debugstr_guid(&input
[i
].type
));
237 ok(IsEqualGUID(&input
[i
].subtype
, expect
->inputs
[i
].subtype
),
238 "got input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
240 for (; expect
->inputs
[i
].subtype
; ++i
)
241 ok(0, "missing input[%u] subtype %s\n", i
, debugstr_guid(expect
->inputs
[i
].subtype
));
242 for (; i
< input_count
; ++i
)
243 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
245 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
247 ok(IsEqualGUID(&output
[i
].type
, expect
->major_type
),
248 "got output[%u] major %s\n", i
, debugstr_guid(&output
[i
].type
));
249 ok(IsEqualGUID(&output
[i
].subtype
, expect
->outputs
[i
].subtype
),
250 "got output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
252 for (; expect
->outputs
[i
].subtype
; ++i
)
253 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
254 for (; i
< output_count
; ++i
)
255 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
258 void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
263 hr
= IMFMediaType_DeleteAllItems(mediatype
);
264 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
266 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
268 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
269 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
273 static void init_dmo_media_type_video(DMO_MEDIA_TYPE
*media_type
,
274 const GUID
*subtype
, const LONG width
, const LONG height
)
276 VIDEOINFOHEADER
*header
= (VIDEOINFOHEADER
*)(media_type
+ 1);
278 memset(header
, 0, sizeof(*header
));
279 header
->bmiHeader
.biSize
= sizeof(header
->bmiHeader
);
280 header
->bmiHeader
.biWidth
= width
;
281 header
->bmiHeader
.biHeight
= height
;
282 header
->bmiHeader
.biCompression
= subtype
->Data1
;
284 media_type
->majortype
= MEDIATYPE_Video
;
285 media_type
->subtype
= *subtype
;
286 media_type
->bFixedSizeSamples
= FALSE
;
287 media_type
->bTemporalCompression
= TRUE
;
288 media_type
->lSampleSize
= 0;
289 media_type
->formattype
= FORMAT_VideoInfo
;
290 media_type
->pUnk
= NULL
;
291 media_type
->cbFormat
= sizeof(*header
) + 4; /* 4 bytes codec data. */
292 media_type
->pbFormat
= (BYTE
*)header
;
295 static void check_mft_optional_methods(IMFTransform
*transform
, DWORD output_count
)
297 DWORD in_id
, out_id
, in_count
, out_count
, in_min
, in_max
, out_min
, out_max
;
298 PROPVARIANT propvar
= {.vt
= VT_EMPTY
};
299 IMFMediaEvent
*event
;
302 in_min
= in_max
= out_min
= out_max
= 0xdeadbeef;
303 hr
= IMFTransform_GetStreamLimits(transform
, &in_min
, &in_max
, &out_min
, &out_max
);
304 ok(hr
== S_OK
, "GetStreamLimits returned %#lx\n", hr
);
305 ok(in_min
== 1, "got input_min %lu\n", in_min
);
306 ok(in_max
== 1, "got input_max %lu\n", in_max
);
307 ok(out_min
== output_count
, "got output_min %lu\n", out_min
);
308 ok(out_max
== output_count
, "got output_max %lu\n", out_max
);
310 in_count
= out_count
= 0xdeadbeef;
311 hr
= IMFTransform_GetStreamCount(transform
, &in_count
, &out_count
);
312 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
313 ok(in_count
== 1, "got input_count %lu\n", in_count
);
314 ok(out_count
== output_count
, "got output_count %lu\n", out_count
);
316 in_count
= out_count
= 1;
317 in_id
= out_id
= 0xdeadbeef;
318 hr
= IMFTransform_GetStreamIDs(transform
, in_count
, &in_id
, out_count
, &out_id
);
319 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
321 hr
= IMFTransform_DeleteInputStream(transform
, 0);
322 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
323 hr
= IMFTransform_DeleteInputStream(transform
, 1);
324 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
326 hr
= IMFTransform_AddInputStreams(transform
, 0, NULL
);
327 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
329 hr
= IMFTransform_AddInputStreams(transform
, 1, &in_id
);
330 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
332 hr
= IMFTransform_SetOutputBounds(transform
, 0, 0);
333 ok(hr
== E_NOTIMPL
|| hr
== S_OK
, "SetOutputBounds returned %#lx\n", hr
);
335 hr
= MFCreateMediaEvent(MEEndOfStream
, &GUID_NULL
, S_OK
, &propvar
, &event
);
336 ok(hr
== S_OK
, "MFCreateMediaEvent returned %#lx\n", hr
);
337 hr
= IMFTransform_ProcessEvent(transform
, 0, NULL
);
338 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
|| hr
== E_INVALIDARG
, "ProcessEvent returned %#lx\n", hr
);
339 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
340 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
341 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
342 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
343 IMFMediaEvent_Release(event
);
346 static void check_mft_get_attributes(IMFTransform
*transform
, const struct attribute_desc
*expect_transform_attributes
,
347 BOOL expect_output_attributes
)
349 IMFAttributes
*attributes
, *tmp_attributes
;
354 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
355 todo_wine_if(expect_transform_attributes
&& hr
== E_NOTIMPL
)
356 ok(hr
== (expect_transform_attributes
? S_OK
: E_NOTIMPL
), "GetAttributes returned %#lx\n", hr
);
359 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
360 check_attributes(attributes
, expect_transform_attributes
, -1);
362 hr
= IMFTransform_GetAttributes(transform
, &tmp_attributes
);
363 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
364 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
365 IMFAttributes_Release(tmp_attributes
);
367 ref
= IMFAttributes_Release(attributes
);
368 ok(ref
== 1, "Release returned %lu\n", ref
);
371 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
372 todo_wine_if(expect_output_attributes
&& hr
== E_NOTIMPL
)
373 ok(hr
== (expect_output_attributes
? S_OK
: E_NOTIMPL
)
374 || broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
375 "GetOutputStreamAttributes returned %#lx\n", hr
);
378 ok(hr
== S_OK
, "GetOutputStreamAttributes returned %#lx\n", hr
);
381 hr
= IMFAttributes_GetCount(attributes
, &count
);
382 ok(hr
== S_OK
, "GetCount returned %#lx\n", hr
);
383 ok(!count
, "got %u attributes\n", count
);
385 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &tmp_attributes
);
386 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
387 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
388 IMFAttributes_Release(tmp_attributes
);
390 ref
= IMFAttributes_Release(attributes
);
391 ok(ref
== 1, "Release returned %lu\n", ref
);
393 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, NULL
);
394 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
395 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 1, &attributes
);
396 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
399 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
400 ok(hr
== E_NOTIMPL
|| broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
401 "GetInputStreamAttributes returned %#lx\n", hr
);
404 #define check_mft_input_stream_info(a, b) check_mft_input_stream_info_(__LINE__, a, b)
405 static void check_mft_input_stream_info_(int line
, MFT_INPUT_STREAM_INFO
*value
, const MFT_INPUT_STREAM_INFO
*expect
)
407 check_member_(__FILE__
, line
, *value
, *expect
, "%I64d", hnsMaxLatency
);
408 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
409 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
410 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbMaxLookahead
);
411 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
414 #define check_mft_get_input_stream_info(a, b, c) check_mft_get_input_stream_info_(__LINE__, a, b, c)
415 static void check_mft_get_input_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_INPUT_STREAM_INFO
*expect
)
417 MFT_INPUT_STREAM_INFO info
, empty
= {0};
420 memset(&info
, 0xcd, sizeof(info
));
421 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &info
);
422 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetInputStreamInfo returned %#lx\n", hr
);
423 check_mft_input_stream_info_(line
, &info
, expect
? expect
: &empty
);
426 #define check_mft_output_stream_info(a, b) check_mft_output_stream_info_(__LINE__, a, b)
427 static void check_mft_output_stream_info_(int line
, MFT_OUTPUT_STREAM_INFO
*value
, const MFT_OUTPUT_STREAM_INFO
*expect
)
429 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
430 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
431 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
434 #define check_mft_get_output_stream_info(a, b, c) check_mft_get_output_stream_info_(__LINE__, a, b, c)
435 static void check_mft_get_output_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_OUTPUT_STREAM_INFO
*expect
)
437 MFT_OUTPUT_STREAM_INFO info
, empty
= {0};
440 memset(&info
, 0xcd, sizeof(info
));
441 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
442 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetOutputStreamInfo returned %#lx\n", hr
);
443 check_mft_output_stream_info_(line
, &info
, expect
? expect
: &empty
);
446 #define check_mft_set_input_type_required(a, b) check_mft_set_input_type_required_(__LINE__, a, b)
447 static void check_mft_set_input_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
449 const struct attribute_desc
*attr
;
450 IMFMediaType
*media_type
;
454 hr
= MFCreateMediaType(&media_type
);
455 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
456 init_media_type(media_type
, attributes
, -1);
458 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
460 winetest_push_context("%s", debugstr_a(attr
->name
));
461 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
462 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
463 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
464 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetInputType returned %#lx.\n", hr
);
465 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
466 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
467 winetest_pop_context();
470 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
471 ok_(__FILE__
, line
)(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
472 ref
= IMFMediaType_Release(media_type
);
473 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
476 static void check_mft_set_input_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
)
478 IMFMediaType
*media_type
;
481 hr
= MFCreateMediaType(&media_type
);
482 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
483 init_media_type(media_type
, attributes
, -1);
485 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
486 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
487 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
488 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
490 IMFMediaType_Release(media_type
);
493 #define check_mft_get_input_current_type(a, b) check_mft_get_input_current_type_(a, b, FALSE, FALSE)
494 static void check_mft_get_input_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
495 BOOL todo_current
, BOOL todo_compare
)
497 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
498 IMFMediaType
*media_type
, *current_type
;
501 hr
= IMFTransform_GetInputCurrentType(transform
, 0, ¤t_type
);
502 todo_wine_if(todo_current
)
503 ok(hr
== expect_hr
, "GetInputCurrentType returned hr %#lx.\n", hr
);
507 hr
= MFCreateMediaType(&media_type
);
508 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
509 init_media_type(media_type
, attributes
, -1);
511 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
512 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
513 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
514 todo_wine_if(todo_compare
)
515 ok(result
, "got result %u.\n", !!result
);
517 IMFMediaType_Release(media_type
);
518 IMFMediaType_Release(current_type
);
521 #define check_mft_set_output_type_required(a, b) check_mft_set_output_type_required_(__LINE__, a, b)
522 static void check_mft_set_output_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
524 const struct attribute_desc
*attr
;
525 IMFMediaType
*media_type
;
529 hr
= MFCreateMediaType(&media_type
);
530 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
531 init_media_type(media_type
, attributes
, -1);
533 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
535 winetest_push_context("%s", debugstr_a(attr
->name
));
536 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
537 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
538 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
539 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetOutputType returned %#lx.\n", hr
);
540 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
541 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
542 winetest_pop_context();
545 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
546 ok_(__FILE__
, line
)(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
547 ref
= IMFMediaType_Release(media_type
);
548 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
551 static void check_mft_set_output_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
554 IMFMediaType
*media_type
;
557 hr
= MFCreateMediaType(&media_type
);
558 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
559 init_media_type(media_type
, attributes
, -1);
561 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
562 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
563 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
564 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
566 IMFMediaType_Release(media_type
);
569 #define check_mft_get_output_current_type(a, b) check_mft_get_output_current_type_(a, b, FALSE, FALSE)
570 static void check_mft_get_output_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
571 BOOL todo_current
, BOOL todo_compare
)
573 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
574 IMFMediaType
*media_type
, *current_type
;
577 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, ¤t_type
);
578 todo_wine_if(todo_current
)
579 ok(hr
== expect_hr
, "GetOutputCurrentType returned hr %#lx.\n", hr
);
583 hr
= MFCreateMediaType(&media_type
);
584 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
585 init_media_type(media_type
, attributes
, -1);
587 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
588 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
589 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
590 todo_wine_if(todo_compare
)
591 ok(result
, "got result %u.\n", !!result
);
593 IMFMediaType_Release(media_type
);
594 IMFMediaType_Release(current_type
);
597 #define check_mft_process_output(a, b, c) check_mft_process_output_(__LINE__, a, b, c)
598 static HRESULT
check_mft_process_output_(int line
, IMFTransform
*transform
, IMFSample
*output_sample
, DWORD
*output_status
)
600 static const DWORD expect_flags
= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
| MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
601 | MFT_OUTPUT_DATA_BUFFER_STREAM_END
| MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
602 MFT_OUTPUT_DATA_BUFFER output
[3];
607 memset(&output
, 0, sizeof(output
));
608 output
[0].pSample
= output_sample
;
609 output
[0].dwStreamID
= 0;
610 ret
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
611 ok_(__FILE__
, line
)(output
[0].dwStreamID
== 0, "got dwStreamID %#lx\n", output
[0].dwStreamID
);
612 ok_(__FILE__
, line
)(output
[0].pEvents
== NULL
, "got pEvents %p\n", output
[0].pEvents
);
613 ok_(__FILE__
, line
)(output
[0].pSample
== output_sample
, "got pSample %p\n", output
[0].pSample
);
614 ok_(__FILE__
, line
)((output
[0].dwStatus
& ~expect_flags
) == 0
615 || broken((output
[0].dwStatus
& ~expect_flags
) == 6) /* Win7 */
616 || broken((output
[0].dwStatus
& ~expect_flags
) == 7) /* Win7 */,
617 "got dwStatus %#lx\n", output
[0].dwStatus
);
618 *output_status
= output
[0].dwStatus
& expect_flags
;
621 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
622 else if (ret
== MF_E_TRANSFORM_STREAM_CHANGE
)
623 ok_(__FILE__
, line
)(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
624 "got status %#lx\n", status
);
627 if (*output_status
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
)
629 hr
= IMFSample_SetUINT32(output_sample
, &mft_output_sample_incomplete
, 1);
630 ok_(__FILE__
, line
)(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
634 hr
= IMFSample_DeleteItem(output_sample
, &mft_output_sample_incomplete
);
635 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
637 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
643 DWORD
compare_nv12(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
645 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
647 /* skip BMP header and RGB data from the dump */
648 size
= *(DWORD
*)(expect
+ 2);
649 *length
= *length
+ size
;
650 expect
= expect
+ size
;
652 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
654 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
655 for (x
= 0; x
< width
; x
++)
657 if (x
< rect
->left
|| x
>= rect
->right
) continue;
658 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
662 for (y
= 0; y
< height
; y
+= 2, data
+= width
, expect
+= width
)
664 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
665 for (x
= 0; x
< width
; x
+= 2)
667 if (x
< rect
->left
|| x
>= rect
->right
) continue;
668 diff
+= abs((int)expect
[x
+ 0] - (int)data
[x
+ 0]);
669 diff
+= abs((int)expect
[x
+ 1] - (int)data
[x
+ 1]);
673 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
674 return diff
* 100 / 256 / size
;
677 DWORD
compare_i420(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
679 DWORD i
, x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
681 /* skip BMP header and RGB data from the dump */
682 size
= *(DWORD
*)(expect
+ 2);
683 *length
= *length
+ size
;
684 expect
= expect
+ size
;
686 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
688 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
689 for (x
= 0; x
< width
; x
++)
691 if (x
< rect
->left
|| x
>= rect
->right
) continue;
692 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
696 for (i
= 0; i
< 2; ++i
) for (y
= 0; y
< height
; y
+= 2, data
+= width
/ 2, expect
+= width
/ 2)
698 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
699 for (x
= 0; x
< width
; x
+= 2)
701 if (x
< rect
->left
|| x
>= rect
->right
) continue;
702 diff
+= abs((int)expect
[x
/ 2] - (int)data
[x
/ 2]);
706 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
707 return diff
* 100 / 256 / size
;
710 DWORD
compare_rgb32(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
712 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
714 /* skip BMP header from the dump */
715 size
= *(DWORD
*)(expect
+ 2 + 2 * sizeof(DWORD
));
716 *length
= *length
+ size
;
717 expect
= expect
+ size
;
719 for (y
= 0; y
< height
; y
++, data
+= width
* 4, expect
+= width
* 4)
721 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
722 for (x
= 0; x
< width
; x
++)
724 if (x
< rect
->left
|| x
>= rect
->right
) continue;
725 diff
+= abs((int)expect
[4 * x
+ 0] - (int)data
[4 * x
+ 0]);
726 diff
+= abs((int)expect
[4 * x
+ 1] - (int)data
[4 * x
+ 1]);
727 diff
+= abs((int)expect
[4 * x
+ 2] - (int)data
[4 * x
+ 2]);
731 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3;
732 return diff
* 100 / 256 / size
;
735 DWORD
compare_pcm16(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
737 const INT16
*data_pcm
= (INT16
*)data
, *expect_pcm
= (INT16
*)expect
;
738 DWORD i
, size
= *length
/ 2, diff
= 0;
740 for (i
= 0; i
< size
; i
++)
741 diff
+= abs((int)*expect_pcm
++ - (int)*data_pcm
++);
743 return diff
* 100 / 65536 / size
;
746 static DWORD
compare_bytes(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
748 DWORD i
, size
= *length
, diff
= 0;
750 for (i
= 0; i
< size
; i
++)
751 diff
+= abs((int)*expect
++ - (int)*data
++);
753 return diff
* 100 / 256 / size
;
756 void dump_rgb32(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
758 DWORD width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
759 static const char magic
[2] = "BM";
765 BITMAPINFOHEADER biHeader
;
768 .length
= length
+ sizeof(header
) + 2, .offset
= sizeof(header
) + 2,
771 .biSize
= sizeof(BITMAPINFOHEADER
), .biWidth
= width
, .biHeight
= height
, .biPlanes
= 1,
772 .biBitCount
= 32, .biCompression
= BI_RGB
, .biSizeImage
= width
* height
* 4,
778 ret
= WriteFile(output
, magic
, sizeof(magic
), &written
, NULL
);
779 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
780 ok(written
== sizeof(magic
), "written %lu bytes\n", written
);
781 ret
= WriteFile(output
, &header
, sizeof(header
), &written
, NULL
);
782 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
783 ok(written
== sizeof(header
), "written %lu bytes\n", written
);
784 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
785 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
786 ok(written
== length
, "written %lu bytes\n", written
);
789 void dump_nv12(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
791 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
792 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
795 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
797 *rgb32
++ = data
[width
* y
+ x
];
798 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 0];
799 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 1];
803 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
806 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
807 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
808 ok(written
== length
, "written %lu bytes\n", written
);
811 void dump_i420(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
813 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
814 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
817 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
819 *rgb32
++ = data
[width
* y
+ x
];
820 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + x
/ 2];
821 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + (width
/ 2) * (height
/ 2) + x
/ 2];
825 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
828 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
829 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
830 ok(written
== length
, "written %lu bytes\n", written
);
833 typedef void (*enum_mf_media_buffers_cb
)(IMFMediaBuffer
*buffer
, const struct buffer_desc
*desc
, void *context
);
834 static void enum_mf_media_buffers(IMFSample
*sample
, const struct sample_desc
*sample_desc
,
835 enum_mf_media_buffers_cb callback
, void *context
)
837 IMFMediaBuffer
*buffer
;
841 for (i
= 0; SUCCEEDED(hr
= IMFSample_GetBufferByIndex(sample
, i
, &buffer
)); i
++)
843 winetest_push_context("buffer %lu", i
);
844 ok(hr
== S_OK
, "GetBufferByIndex returned %#lx\n", hr
);
845 ok(i
< sample_desc
->buffer_count
, "got unexpected buffer\n");
847 callback(buffer
, sample_desc
->buffers
+ i
, context
);
849 IMFMediaBuffer_Release(buffer
);
850 winetest_pop_context();
852 ok(hr
== E_INVALIDARG
, "GetBufferByIndex returned %#lx\n", hr
);
855 struct enum_mf_sample_state
857 const struct sample_desc
*next_sample
;
858 struct sample_desc sample
;
861 typedef void (*enum_mf_sample_cb
)(IMFSample
*sample
, const struct sample_desc
*sample_desc
, void *context
);
862 static void enum_mf_samples(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
863 enum_mf_sample_cb callback
, void *context
)
865 struct enum_mf_sample_state state
= {.next_sample
= collection_desc
};
870 for (i
= 0; SUCCEEDED(hr
= IMFCollection_GetElement(samples
, i
, (IUnknown
**)&sample
)); i
++)
872 winetest_push_context("sample %lu", i
);
873 ok(hr
== S_OK
, "GetElement returned %#lx\n", hr
);
875 state
.sample
.sample_time
+= state
.sample
.sample_duration
;
876 if (!state
.sample
.repeat_count
--)
877 state
.sample
= *state
.next_sample
++;
879 callback(sample
, &state
.sample
, context
);
881 IMFSample_Release(sample
);
882 winetest_pop_context();
884 ok(hr
== E_INVALIDARG
, "GetElement returned %#lx\n", hr
);
887 static void dump_mf_media_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*buffer_desc
, HANDLE output
)
889 DWORD length
, written
;
894 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
895 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
897 if (buffer_desc
->dump
)
898 buffer_desc
->dump(data
, length
, &buffer_desc
->rect
, output
);
901 if (buffer_desc
->length
== -1)
903 ret
= WriteFile(output
, &length
, sizeof(length
), &written
, NULL
);
904 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
905 ok(written
== sizeof(length
), "written %lu bytes\n", written
);
908 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
909 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
910 ok(written
== length
, "written %lu bytes\n", written
);
913 hr
= IMFMediaBuffer_Unlock(buffer
);
914 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
917 static void dump_mf_sample(IMFSample
*sample
, const struct sample_desc
*sample_desc
, HANDLE output
)
919 enum_mf_media_buffers(sample
, sample_desc
, dump_mf_media_buffer
, output
);
922 static void dump_mf_sample_collection(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
923 const WCHAR
*output_filename
)
925 WCHAR path
[MAX_PATH
];
928 GetTempPathW(ARRAY_SIZE(path
), path
);
929 lstrcatW(path
, output_filename
);
931 output
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
932 ok(output
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
934 enum_mf_samples(samples
, collection_desc
, dump_mf_sample
, output
);
936 trace("created %s\n", debugstr_w(path
));
940 #define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__FILE__, __LINE__, a, b, c)
941 static DWORD
check_mf_media_buffer_(const char *file
, int line
, IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
,
942 const BYTE
**expect_data
, DWORD
*expect_data_len
)
944 DWORD length
, diff
= 0, expect_length
= expect
->length
;
948 if (expect_length
== -1)
950 expect_length
= *(DWORD
*)*expect_data
;
951 *expect_data
= *expect_data
+ sizeof(DWORD
);
952 *expect_data_len
= *expect_data_len
- sizeof(DWORD
);
955 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
956 ok_(file
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
957 todo_wine_if(expect
->todo_length
)
958 ok_(file
, line
)(length
== expect_length
, "got length %#lx\n", length
);
960 if (*expect_data_len
< length
)
961 todo_wine_if(expect
->todo_length
)
962 ok_(file
, line
)(0, "missing %#lx bytes\n", length
- *expect_data_len
);
963 else if (!expect
->compare
)
964 diff
= compare_bytes(data
, &length
, NULL
, *expect_data
);
966 diff
= expect
->compare(data
, &length
, &expect
->rect
, *expect_data
);
968 hr
= IMFMediaBuffer_Unlock(buffer
);
969 ok_(file
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
971 *expect_data
= *expect_data
+ min(length
, *expect_data_len
);
972 *expect_data_len
= *expect_data_len
- min(length
, *expect_data_len
);
977 struct check_mf_sample_context
987 static void check_mf_sample_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
, void *context
)
989 struct check_mf_sample_context
*ctx
= context
;
990 DWORD expect_length
= expect
->length
== -1 ? *(DWORD
*)ctx
->data
: expect
->length
;
991 ctx
->diff
+= check_mf_media_buffer_(ctx
->file
, ctx
->line
, buffer
, expect
, &ctx
->data
, &ctx
->data_len
);
992 ctx
->total_length
+= expect_length
;
995 #define check_mf_sample(a, b, c, d) check_mf_sample_(__FILE__, __LINE__, a, b, c, d)
996 static DWORD
check_mf_sample_(const char *file
, int line
, IMFSample
*sample
, const struct sample_desc
*expect
,
997 const BYTE
**expect_data
, DWORD
*expect_data_len
)
999 struct check_mf_sample_context ctx
= {.data
= *expect_data
, .data_len
= *expect_data_len
, .file
= file
, .line
= line
};
1000 DWORD buffer_count
, total_length
, sample_flags
;
1004 if (expect
->attributes
)
1005 check_attributes_(file
, line
, (IMFAttributes
*)sample
, expect
->attributes
, -1);
1007 buffer_count
= 0xdeadbeef;
1008 hr
= IMFSample_GetBufferCount(sample
, &buffer_count
);
1009 ok_(file
, line
)(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
1010 ok_(file
, line
)(buffer_count
== expect
->buffer_count
,
1011 "got %lu buffers\n", buffer_count
);
1013 sample_flags
= 0xdeadbeef;
1014 hr
= IMFSample_GetSampleFlags(sample
, &sample_flags
);
1015 ok_(file
, line
)(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
1016 ok_(file
, line
)(sample_flags
== 0,
1017 "got sample flags %#lx\n", sample_flags
);
1019 timestamp
= 0xdeadbeef;
1020 hr
= IMFSample_GetSampleTime(sample
, ×tamp
);
1021 ok_(file
, line
)(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
1022 todo_wine_if(expect
->todo_time
&& timestamp
== expect
->todo_time
)
1023 ok_(file
, line
)(llabs(timestamp
- expect
->sample_time
) <= 50,
1024 "got sample time %I64d\n", timestamp
);
1026 timestamp
= 0xdeadbeef;
1027 hr
= IMFSample_GetSampleDuration(sample
, ×tamp
);
1028 ok_(file
, line
)(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
1029 todo_wine_if(expect
->todo_length
)
1030 ok_(file
, line
)(llabs(timestamp
- expect
->sample_duration
) <= 1,
1031 "got sample duration %I64d\n", timestamp
);
1033 enum_mf_media_buffers(sample
, expect
, check_mf_sample_buffer
, &ctx
);
1035 total_length
= 0xdeadbeef;
1036 hr
= IMFSample_GetTotalLength(sample
, &total_length
);
1037 ok_(file
, line
)(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1038 todo_wine_if(expect
->todo_length
)
1039 ok_(file
, line
)(total_length
== ctx
.total_length
,
1040 "got total length %#lx\n", total_length
);
1041 ok_(file
, line
)(*expect_data_len
>= ctx
.total_length
,
1042 "missing %#lx data\n", ctx
.total_length
- *expect_data_len
);
1044 *expect_data
= ctx
.data
;
1045 *expect_data_len
= ctx
.data_len
;
1047 return ctx
.diff
/ buffer_count
;
1050 static void check_mf_sample_collection_enum(IMFSample
*sample
, const struct sample_desc
*expect
, void *context
)
1052 struct check_mf_sample_context
*ctx
= context
;
1053 ctx
->diff
+= check_mf_sample_(ctx
->file
, ctx
->line
, sample
, expect
, &ctx
->data
, &ctx
->data_len
);
1056 DWORD
check_mf_sample_collection_(const char *file
, int line
, IMFCollection
*samples
,
1057 const struct sample_desc
*expect_samples
, const WCHAR
*expect_data_filename
)
1059 struct check_mf_sample_context ctx
= {.file
= file
, .line
= line
};
1063 load_resource(expect_data_filename
, &ctx
.data
, &ctx
.data_len
);
1064 enum_mf_samples(samples
, expect_samples
, check_mf_sample_collection_enum
, &ctx
);
1066 dump_mf_sample_collection(samples
, expect_samples
, expect_data_filename
);
1068 hr
= IMFCollection_GetElementCount(samples
, &count
);
1069 ok_(file
, line
)(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
1071 return ctx
.diff
/ count
;
1074 #define check_video_info_header(a, b) check_video_info_header_(__LINE__, a, b)
1075 static void check_video_info_header_(int line
, VIDEOINFOHEADER
*info
, const VIDEOINFOHEADER
*expected
)
1077 ok_(__FILE__
, line
)(info
->rcSource
.left
== expected
->rcSource
.left
1078 && info
->rcSource
.top
== expected
->rcSource
.top
1079 && info
->rcSource
.right
== expected
->rcSource
.right
1080 && info
->rcSource
.bottom
== expected
->rcSource
.bottom
,
1081 "Got unexpected rcSource {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1082 info
->rcSource
.left
, info
->rcSource
.top
, info
->rcSource
.right
, info
->rcSource
.bottom
,
1083 expected
->rcSource
.left
, expected
->rcSource
.top
, expected
->rcSource
.right
, expected
->rcSource
.bottom
);
1084 ok_(__FILE__
, line
)(info
->rcTarget
.left
== expected
->rcTarget
.left
1085 && info
->rcTarget
.top
== expected
->rcTarget
.top
1086 && info
->rcTarget
.right
== expected
->rcTarget
.right
1087 && info
->rcTarget
.bottom
== expected
->rcTarget
.bottom
,
1088 "Got unexpected rcTarget {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1089 info
->rcTarget
.left
, info
->rcTarget
.top
, info
->rcTarget
.right
, info
->rcTarget
.bottom
,
1090 expected
->rcTarget
.left
, expected
->rcTarget
.top
, expected
->rcTarget
.right
, expected
->rcTarget
.bottom
);
1091 ok_(__FILE__
, line
)(info
->dwBitRate
== expected
->dwBitRate
,
1092 "Got unexpected dwBitRate %lu, expected %lu.\n",
1093 info
->dwBitRate
, expected
->dwBitRate
);
1094 ok_(__FILE__
, line
)(info
->dwBitErrorRate
== expected
->dwBitErrorRate
,
1095 "Got unexpected dwBitErrorRate %lu, expected %lu.\n",
1096 info
->dwBitErrorRate
, expected
->dwBitErrorRate
);
1097 ok_(__FILE__
, line
)(info
->AvgTimePerFrame
== expected
->AvgTimePerFrame
,
1098 "Got unexpected AvgTimePerFrame %I64d, expected %I64d.\n",
1099 info
->AvgTimePerFrame
, expected
->AvgTimePerFrame
);
1100 ok_(__FILE__
, line
)(info
->bmiHeader
.biSize
== expected
->bmiHeader
.biSize
,
1101 "Got unexpected bmiHeader.biSize %lu, expected %lu.\n",
1102 info
->bmiHeader
.biSize
, expected
->bmiHeader
.biSize
);
1103 ok_(__FILE__
, line
)(info
->bmiHeader
.biWidth
== expected
->bmiHeader
.biWidth
,
1104 "Got unexpected bmiHeader.biWidth %ld, expected %ld.\n",
1105 info
->bmiHeader
.biWidth
, expected
->bmiHeader
.biWidth
);
1106 ok_(__FILE__
, line
)(info
->bmiHeader
.biHeight
== expected
->bmiHeader
.biHeight
,
1107 "Got unexpected bmiHeader.biHeight %ld, expected %ld.\n",
1108 info
->bmiHeader
.biHeight
, expected
->bmiHeader
.biHeight
);
1109 ok_(__FILE__
, line
)(info
->bmiHeader
.biPlanes
== expected
->bmiHeader
.biPlanes
,
1110 "Got unexpected bmiHeader.biPlanes %u, expected %u.\n",
1111 info
->bmiHeader
.biPlanes
, expected
->bmiHeader
.biPlanes
);
1112 ok_(__FILE__
, line
)(info
->bmiHeader
.biBitCount
== expected
->bmiHeader
.biBitCount
,
1113 "Got unexpected bmiHeader.biBitCount %u, expected %u.\n",
1114 info
->bmiHeader
.biBitCount
, expected
->bmiHeader
.biBitCount
);
1115 ok_(__FILE__
, line
)(info
->bmiHeader
.biCompression
== expected
->bmiHeader
.biCompression
,
1116 "Got unexpected bmiHeader.biCompression %#lx, expected %#lx.\n",
1117 info
->bmiHeader
.biCompression
, expected
->bmiHeader
.biCompression
);
1118 ok_(__FILE__
, line
)(info
->bmiHeader
.biSizeImage
== expected
->bmiHeader
.biSizeImage
,
1119 "Got unexpected bmiHeader.biSizeImage %lu, expected %lu.\n",
1120 info
->bmiHeader
.biSizeImage
, expected
->bmiHeader
.biSizeImage
);
1121 ok_(__FILE__
, line
)(info
->bmiHeader
.biXPelsPerMeter
== expected
->bmiHeader
.biXPelsPerMeter
,
1122 "Got unexpected bmiHeader.biXPelsPerMeter %ld, expected %ld.\n",
1123 info
->bmiHeader
.biXPelsPerMeter
, expected
->bmiHeader
.biXPelsPerMeter
);
1124 ok_(__FILE__
, line
)(info
->bmiHeader
.biYPelsPerMeter
== expected
->bmiHeader
.biYPelsPerMeter
,
1125 "Got unexpected bmiHeader.xxxxxx %ld, expected %ld.\n",
1126 info
->bmiHeader
.biYPelsPerMeter
, expected
->bmiHeader
.biYPelsPerMeter
);
1127 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrUsed
== expected
->bmiHeader
.biClrUsed
,
1128 "Got unexpected bmiHeader.biClrUsed %lu, expected %lu.\n",
1129 info
->bmiHeader
.biClrUsed
, expected
->bmiHeader
.biClrUsed
);
1130 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrImportant
== expected
->bmiHeader
.biClrImportant
,
1131 "Got unexpected bmiHeader.biClrImportant %lu, expected %lu.\n",
1132 info
->bmiHeader
.biClrImportant
, expected
->bmiHeader
.biClrImportant
);
1135 #define check_dmo_media_type(a, b) check_dmo_media_type_(__LINE__, a, b)
1136 static void check_dmo_media_type_(int line
, DMO_MEDIA_TYPE
*media_type
, const DMO_MEDIA_TYPE
*expected
)
1138 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->majortype
, &expected
->majortype
),
1139 "Got unexpected majortype %s, expected %s.\n",
1140 debugstr_guid(&media_type
->majortype
), debugstr_guid(&expected
->majortype
));
1141 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->subtype
, &expected
->subtype
),
1142 "Got unexpected subtype %s, expected %s.\n",
1143 debugstr_guid(&media_type
->subtype
), debugstr_guid(&expected
->subtype
));
1144 ok_(__FILE__
, line
)(media_type
->bFixedSizeSamples
== expected
->bFixedSizeSamples
,
1145 "Got unexpected bFixedSizeSamples %d, expected %d.\n",
1146 media_type
->bFixedSizeSamples
, expected
->bFixedSizeSamples
);
1147 ok_(__FILE__
, line
)(media_type
->bTemporalCompression
== expected
->bTemporalCompression
,
1148 "Got unexpected bTemporalCompression %d, expected %d.\n",
1149 media_type
->bTemporalCompression
, expected
->bTemporalCompression
);
1150 ok_(__FILE__
, line
)(media_type
->lSampleSize
== expected
->lSampleSize
,
1151 "Got unexpected lSampleSize %lu, expected %lu.\n",
1152 media_type
->lSampleSize
, expected
->lSampleSize
);
1153 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->formattype
, &expected
->formattype
),
1154 "Got unexpected formattype %s.\n",
1155 debugstr_guid(&media_type
->formattype
));
1156 ok_(__FILE__
, line
)(media_type
->pUnk
== NULL
, "Got unexpected pUnk %p.\n", media_type
->pUnk
);
1157 ok_(__FILE__
, line
)(media_type
->cbFormat
== expected
->cbFormat
,
1158 "Got unexpected cbFormat %lu, expected %lu.\n",
1159 media_type
->cbFormat
, expected
->cbFormat
);
1161 if (expected
->pbFormat
)
1163 ok_(__FILE__
, line
)(!!media_type
->pbFormat
, "Got NULL pbFormat.\n");
1164 if (!media_type
->pbFormat
)
1167 if (IsEqualGUID(&media_type
->formattype
, &FORMAT_VideoInfo
)
1168 && IsEqualGUID(&expected
->formattype
, &FORMAT_VideoInfo
))
1169 check_video_info_header((VIDEOINFOHEADER
*)media_type
->pbFormat
, (VIDEOINFOHEADER
*)expected
->pbFormat
);
1173 static void check_dmo_get_input_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1175 DMO_MEDIA_TYPE media_type
;
1179 hr
= IMediaObject_GetInputType(media_object
, 1, 0, NULL
);
1180 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1181 hr
= IMediaObject_GetInputType(media_object
, 1, 0, &media_type
);
1182 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1183 hr
= IMediaObject_GetInputType(media_object
, 1, count
, &media_type
);
1184 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1185 hr
= IMediaObject_GetInputType(media_object
, 0, count
, &media_type
);
1186 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1187 hr
= IMediaObject_GetInputType(media_object
, 0, count
, NULL
);
1188 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1189 hr
= IMediaObject_GetInputType(media_object
, 0, 0xdeadbeef, NULL
);
1190 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1191 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, NULL
);
1192 ok(hr
== S_OK
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1193 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, &media_type
);
1194 ok(hr
== S_OK
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1196 MoFreeMediaType(&media_type
);
1199 while (SUCCEEDED(hr
= IMediaObject_GetInputType(media_object
, 0, ++i
, &media_type
)))
1201 winetest_push_context("in %lu", i
);
1202 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1203 MoFreeMediaType(&media_type
);
1204 winetest_pop_context();
1207 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned unexpected hr %#lx.\n", hr
);
1208 ok(i
== count
, "%lu types.\n", i
);
1211 static void check_dmo_get_output_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1213 DMO_MEDIA_TYPE media_type
;
1217 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, NULL
);
1218 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1219 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, &media_type
);
1220 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1221 hr
= IMediaObject_GetOutputType(media_object
, 1, count
, &media_type
);
1222 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1223 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, &media_type
);
1224 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1225 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, NULL
);
1226 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned unexpected hr %#lx.\n", hr
);
1227 hr
= IMediaObject_GetOutputType(media_object
, 0, 0xdeadbeef, NULL
);
1228 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned unexpected hr %#lx.\n", hr
);
1229 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, NULL
);
1230 ok(hr
== S_OK
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1231 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, &media_type
);
1232 ok(hr
== S_OK
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1234 MoFreeMediaType(&media_type
);
1237 while (SUCCEEDED(hr
= IMediaObject_GetOutputType(media_object
, 0, ++i
, &media_type
)))
1239 winetest_push_context("out %lu", i
);
1240 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1241 MoFreeMediaType(&media_type
);
1242 winetest_pop_context();
1245 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
1246 ok(i
== count
, "%lu types.\n", i
);
1249 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
1251 if (IsEqualIID(riid
, &IID_IUnknown
))
1254 IUnknown_AddRef(iface
);
1259 return E_NOINTERFACE
;
1262 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
1267 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
1272 static const IUnknownVtbl test_unk_vtbl
=
1274 test_unk_QueryInterface
,
1279 static BOOL
is_supported_video_type(const GUID
*guid
)
1281 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
1282 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
1283 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
1284 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
1285 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
1286 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
1287 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
1288 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
1289 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
1290 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
1291 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
1292 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
1293 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
1294 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
1295 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
1296 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
1297 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
1298 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
1299 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
1300 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
1301 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
1302 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
1303 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
1304 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
1305 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
1306 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
1307 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
1308 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
1309 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
1310 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
1311 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
1314 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
1320 hr
= IMFMediaType_GetMajorType(type
, &major
);
1321 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
1323 hr
= IMFMediaType_GetCount(type
, &count
);
1324 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
1325 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
1327 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
1330 static void test_sample_copier(void)
1332 static const struct attribute_desc expect_transform_attributes
[] =
1334 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, 1),
1337 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 16 * 16};
1338 const MFT_INPUT_STREAM_INFO initial_input_info
= {0}, input_info
= {.cbSize
= 16 * 16};
1339 IMFMediaType
*mediatype
, *mediatype2
;
1340 IMFSample
*sample
, *client_sample
;
1341 IMFMediaBuffer
*media_buffer
;
1342 MFT_INPUT_STREAM_INFO info
;
1343 DWORD flags
, output_status
;
1344 IMFTransform
*copier
;
1348 if (!pMFCreateSampleCopierMFT
)
1350 win_skip("MFCreateSampleCopierMFT() is not available.\n");
1354 winetest_push_context("copier");
1356 hr
= pMFCreateSampleCopierMFT(&copier
);
1357 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1359 check_interface(copier
, &IID_IMFTransform
, TRUE
);
1360 check_interface(copier
, &IID_IMediaObject
, FALSE
);
1361 check_interface(copier
, &IID_IPropertyStore
, FALSE
);
1362 check_interface(copier
, &IID_IPropertyBag
, FALSE
);
1364 check_mft_optional_methods(copier
, 1);
1365 check_mft_get_attributes(copier
, expect_transform_attributes
, FALSE
);
1367 /* Available types. */
1368 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
1369 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1370 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1371 IMFMediaType_Release(mediatype
);
1373 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
1374 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1375 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1376 IMFMediaType_Release(mediatype
);
1378 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
1379 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1381 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
1382 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1384 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
1385 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1387 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
1388 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1390 check_mft_get_input_current_type(copier
, NULL
);
1391 check_mft_get_output_current_type(copier
, NULL
);
1393 hr
= MFCreateSample(&sample
);
1394 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1396 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1397 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1399 hr
= MFCreateMediaType(&mediatype
);
1400 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1402 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1403 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
1405 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1406 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1408 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
1409 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1411 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1412 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1414 check_mft_get_input_stream_info(copier
, S_OK
, &initial_input_info
);
1415 check_mft_get_output_stream_info(copier
, S_OK
, &initial_output_info
);
1417 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1418 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1420 memset(&info
, 0xcd, sizeof(info
));
1421 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &info
);
1422 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
1423 check_member(info
, initial_input_info
, "%I64d", hnsMaxLatency
);
1424 check_member(info
, initial_input_info
, "%#lx", dwFlags
);
1426 check_member(info
, initial_input_info
, "%#lx", cbSize
);
1427 check_member(info
, initial_input_info
, "%#lx", cbMaxLookahead
);
1428 check_member(info
, initial_input_info
, "%#lx", cbAlignment
);
1429 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1431 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1432 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1433 IMFMediaType_Release(mediatype2
);
1435 check_mft_get_input_current_type(copier
, NULL
);
1437 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1438 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1440 /* Setting input type resets output type. */
1441 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1442 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1443 IMFMediaType_Release(mediatype2
);
1445 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1446 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1448 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1449 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1451 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
1452 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1453 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
1454 IMFMediaType_Release(mediatype2
);
1456 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1457 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1459 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
1460 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1461 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
1462 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1463 IMFMediaType_Release(mediatype2
);
1465 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1466 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1467 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
1469 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
1470 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1471 IMFMediaType_Release(mediatype2
);
1473 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1474 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1476 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1477 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
1479 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1480 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1481 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1483 /* Pushing samples. */
1484 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1485 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1487 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1488 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1489 IMFMediaBuffer_Release(media_buffer
);
1491 EXPECT_REF(sample
, 1);
1492 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1493 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1494 EXPECT_REF(sample
, 2);
1496 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1497 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1498 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1500 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1501 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1502 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
1504 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1505 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
1507 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1508 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1510 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1511 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1513 hr
= MFCreateSample(&client_sample
);
1514 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1516 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
1517 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1518 IMFMediaBuffer_Release(media_buffer
);
1520 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1521 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1522 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1523 EXPECT_REF(sample
, 1);
1525 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1526 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
1527 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1530 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1531 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1532 EXPECT_REF(sample
, 2);
1534 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
1535 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1537 ref
= IMFSample_Release(sample
);
1538 ok(ref
== 0, "Release returned %ld\n", ref
);
1539 ref
= IMFSample_Release(client_sample
);
1540 ok(ref
== 0, "Release returned %ld\n", ref
);
1542 ref
= IMFTransform_Release(copier
);
1543 ok(ref
== 0, "Release returned %ld\n", ref
);
1544 ref
= IMFMediaType_Release(mediatype
);
1545 ok(ref
== 0, "Release returned %ld\n", ref
);
1547 winetest_pop_context();
1550 struct sample_metadata
1557 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
1558 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
1560 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
1561 IMFSample
*input_sample
, *output_sample
;
1562 DWORD flags
, output_status
;
1567 hr
= MFCreateSample(&input_sample
);
1568 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1572 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
1573 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1575 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
1576 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1578 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
1579 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1582 hr
= MFCreateSample(&output_sample
);
1583 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1585 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
1586 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1588 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
1589 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1591 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
1592 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1594 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
1595 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1597 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
1598 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1600 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
1601 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1603 hr
= check_mft_process_output(copier
, output_sample
, &output_status
);
1604 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1605 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1607 if (!md
) md
= &zero_md
;
1609 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
1610 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1611 ok(md
->flags
== flags
, "Unexpected flags.\n");
1612 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
1613 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1614 ok(md
->time
== time
, "Unexpected time.\n");
1615 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
1616 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1617 ok(md
->duration
== time
, "Unexpected duration.\n");
1619 ref
= IMFSample_Release(input_sample
);
1620 ok(ref
== 0, "Release returned %ld\n", ref
);
1621 ref
= IMFSample_Release(output_sample
);
1622 ok(ref
== 0, "Release returned %ld\n", ref
);
1625 static void test_sample_copier_output_processing(void)
1627 IMFMediaBuffer
*input_buffer
, *output_buffer
;
1628 MFT_OUTPUT_STREAM_INFO output_info
;
1629 struct sample_metadata md
;
1630 IMFMediaType
*mediatype
;
1631 IMFTransform
*copier
;
1637 if (!pMFCreateSampleCopierMFT
)
1640 hr
= pMFCreateSampleCopierMFT(&copier
);
1641 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1643 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
1644 hr
= MFCreateMediaType(&mediatype
);
1645 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1647 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1648 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1650 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
1651 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1653 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1654 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1656 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1657 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1659 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1660 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1662 /* Source and destination are linear buffers, destination is twice as large. */
1663 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
1664 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
1666 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
1667 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1669 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1670 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1671 memset(ptr
, 0xcc, max_length
);
1672 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1673 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1675 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
1676 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1678 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
1679 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1680 memset(ptr
, 0xaa, max_length
);
1681 hr
= IMFMediaBuffer_Unlock(input_buffer
);
1682 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1683 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
1684 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1686 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
1688 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1689 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1690 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
1692 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1693 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1698 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
1700 ref
= IMFMediaBuffer_Release(input_buffer
);
1701 ok(ref
== 0, "Release returned %ld\n", ref
);
1702 ref
= IMFMediaBuffer_Release(output_buffer
);
1703 ok(ref
== 0, "Release returned %ld\n", ref
);
1705 ref
= IMFTransform_Release(copier
);
1706 ok(ref
== 0, "Release returned %ld\n", ref
);
1707 ref
= IMFMediaType_Release(mediatype
);
1708 ok(ref
== 0, "Release returned %ld\n", ref
);
1711 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
1713 IMFMediaBuffer
*media_buffer
;
1720 hr
= MFCreateSample(&sample
);
1721 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
1722 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
1723 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
1724 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
1725 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
1726 ok(length
== 0, "got length %lu\n", length
);
1727 if (!data
) memset(buffer
, 0xcd, size
);
1728 else memcpy(buffer
, data
, size
);
1729 hr
= IMFMediaBuffer_Unlock(media_buffer
);
1730 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
1731 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
1732 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
1733 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1734 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
1735 ret
= IMFMediaBuffer_Release(media_buffer
);
1736 ok(ret
== 1, "Release returned %lu\n", ret
);
1741 static const BYTE aac_codec_data
[14] = {0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x08};
1743 static void test_aac_encoder(void)
1745 const GUID
*const class_id
= &CLSID_AACMFTEncoder
;
1746 const struct transform_info expect_mft_info
=
1748 .name
= L
"Microsoft AAC Audio Encoder MFT",
1749 .major_type
= &MFMediaType_Audio
,
1752 {.subtype
= &MFAudioFormat_PCM
},
1756 {.subtype
= &MFAudioFormat_AAC
},
1760 static const struct attribute_desc input_type_desc
[] =
1762 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1763 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
1764 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
1765 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
1766 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1769 const struct attribute_desc output_type_desc
[] =
1771 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
1772 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
1773 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
1774 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
1775 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
1776 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000, .required
= TRUE
),
1780 static const struct attribute_desc expect_input_type_desc
[] =
1782 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
1783 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1784 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
1785 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1786 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1787 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
1788 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1789 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 2),
1790 ATTR_UINT32(MF_MT_AVG_BITRATE
, 44100 * 2 * 8),
1791 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
1792 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
1793 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
1794 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1797 const struct attribute_desc expect_output_type_desc
[] =
1799 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
1800 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1801 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1802 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
1803 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
1804 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
1805 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
1806 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
1807 ATTR_UINT32(MF_MT_AVG_BITRATE
, 96000),
1808 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
1809 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
1810 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1811 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
1812 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
1813 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
)),
1816 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 0x600};
1817 const MFT_INPUT_STREAM_INFO input_info
= {0};
1819 const struct buffer_desc output_buffer_desc
[] =
1821 {.length
= -1 /* variable */},
1823 const struct attribute_desc output_sample_attributes
[] =
1825 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
1828 const struct sample_desc output_sample_desc
[] =
1832 .attributes
= output_sample_attributes
,
1833 .sample_time
= 0, .sample_duration
= 113823,
1834 .buffer_count
= 1, .buffers
= output_buffer_desc
,
1838 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
1839 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
1840 IMFSample
*input_sample
, *output_sample
;
1841 IMFCollection
*output_samples
;
1842 ULONG i
, ret
, audio_data_len
;
1843 DWORD length
, output_status
;
1844 IMFTransform
*transform
;
1845 const BYTE
*audio_data
;
1849 hr
= CoInitialize(NULL
);
1850 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
1852 winetest_push_context("aacenc");
1854 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
1856 check_mft_get_info(class_id
, &expect_mft_info
);
1858 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
1859 &IID_IMFTransform
, (void **)&transform
)))
1862 check_interface(transform
, &IID_IMFTransform
, TRUE
);
1863 check_interface(transform
, &IID_IMediaObject
, FALSE
);
1864 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
1865 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
1867 check_mft_optional_methods(transform
, 1);
1868 check_mft_get_attributes(transform
, NULL
, FALSE
);
1869 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1870 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
1872 check_mft_set_output_type_required(transform
, output_type_desc
);
1873 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
1874 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
1876 check_mft_set_input_type_required(transform
, input_type_desc
);
1877 check_mft_set_input_type(transform
, input_type_desc
);
1878 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
1880 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
1881 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
1883 if (!has_video_processor
)
1885 win_skip("Skipping AAC encoder tests on Win7\n");
1889 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
1890 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
1892 input_sample
= create_sample(audio_data
, audio_data_len
);
1893 hr
= IMFSample_SetSampleTime(input_sample
, 0);
1894 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
1895 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
1896 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
1897 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
1898 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
1899 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
1900 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
1901 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
1902 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
1903 ref
= IMFSample_Release(input_sample
);
1904 ok(ref
<= 1, "Release returned %ld\n", ref
);
1906 hr
= MFCreateCollection(&output_samples
);
1907 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
1909 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1910 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
1912 winetest_push_context("%lu", i
);
1913 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
1914 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
1915 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
1916 ref
= IMFSample_Release(output_sample
);
1917 ok(ref
== 1, "Release returned %ld\n", ref
);
1918 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1919 winetest_pop_context();
1921 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
1922 ret
= IMFSample_Release(output_sample
);
1923 ok(ret
== 0, "Release returned %lu\n", ret
);
1924 ok(i
== 88, "got %lu output samples\n", i
);
1926 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacencdata.bin");
1927 ok(ret
== 0, "got %lu%% diff\n", ret
);
1928 IMFCollection_Release(output_samples
);
1930 output_sample
= create_sample(NULL
, output_info
.cbSize
);
1931 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
1932 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
1933 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
1934 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1935 ok(length
== 0, "got length %lu\n", length
);
1936 ret
= IMFSample_Release(output_sample
);
1937 ok(ret
== 0, "Release returned %lu\n", ret
);
1940 ret
= IMFTransform_Release(transform
);
1941 ok(ret
== 0, "Release returned %lu\n", ret
);
1944 winetest_pop_context();
1948 static void test_aac_decoder(void)
1950 const GUID
*const class_id
= &CLSID_MSAACDecMFT
;
1951 const struct transform_info expect_mft_info
=
1953 .name
= L
"Microsoft AAC Audio Decoder MFT",
1954 .major_type
= &MFMediaType_Audio
,
1957 {.subtype
= &MFAudioFormat_AAC
},
1958 {.subtype
= &MFAudioFormat_RAW_AAC1
},
1959 {.subtype
= &MFAudioFormat_ADTS
, .broken
= TRUE
/* <= w8 */},
1963 {.subtype
= &MFAudioFormat_Float
},
1964 {.subtype
= &MFAudioFormat_PCM
},
1968 static const struct attribute_desc expect_input_attributes
[] =
1970 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
1971 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
1972 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
1973 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 6),
1974 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 24),
1975 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
1976 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 1152000),
1979 static const media_type_desc expect_available_inputs
[] =
1982 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1983 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1984 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
1985 /* MF_MT_USER_DATA with some AAC codec data */
1988 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_RAW_AAC1
),
1991 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1992 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1993 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 1),
1994 /* MF_MT_USER_DATA with some AAC codec data */
1997 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
1998 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
1999 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 3),
2000 /* MF_MT_USER_DATA with some AAC codec data */
2003 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_ADTS
),
2006 static const struct attribute_desc expect_output_attributes
[] =
2008 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2009 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2010 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2011 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2012 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2015 static const media_type_desc expect_available_outputs
[] =
2018 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2019 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2020 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2021 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2022 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4 * 44100),
2025 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2026 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2027 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2028 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
2029 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * 44100),
2032 const struct attribute_desc expect_transform_attributes
[] =
2034 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, !has_video_processor
/* 1 on W7 */, .todo
= TRUE
),
2035 /* more AAC decoder specific attributes from CODECAPI */
2038 const struct attribute_desc input_type_desc
[] =
2040 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2041 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
2042 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2043 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
), .required
= TRUE
),
2044 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2045 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2046 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
2047 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
2048 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2051 static const struct attribute_desc output_type_desc
[] =
2053 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2054 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2055 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2056 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2057 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2060 const MFT_OUTPUT_STREAM_INFO output_info
=
2062 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
,
2065 const MFT_INPUT_STREAM_INFO input_info
=
2067 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
2068 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_INPUT_STREAM_HOLDS_BUFFERS
,
2071 const struct buffer_desc output_buffer_desc
[] =
2075 const struct attribute_desc output_sample_attributes
[] =
2077 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2080 const struct sample_desc output_sample_desc
[] =
2083 .attributes
= output_sample_attributes
+ (has_video_processor
? 0 : 1) /* MFSampleExtension_CleanPoint missing on Win7 */,
2084 .sample_time
= 0, .sample_duration
= 232200,
2085 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2089 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2090 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
2091 IMFSample
*input_sample
, *output_sample
;
2092 ULONG i
, ret
, ref
, aacenc_data_len
;
2093 IMFCollection
*output_samples
;
2094 DWORD length
, output_status
;
2095 IMFMediaType
*media_type
;
2096 IMFTransform
*transform
;
2097 const BYTE
*aacenc_data
;
2100 hr
= CoInitialize(NULL
);
2101 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2103 winetest_push_context("aacdec");
2105 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2107 check_mft_get_info(class_id
, &expect_mft_info
);
2109 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2110 &IID_IMFTransform
, (void **)&transform
)))
2113 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2114 check_interface(transform
, &IID_IMediaObject
, FALSE
);
2115 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
2116 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
2118 check_mft_optional_methods(transform
, 1);
2119 check_mft_get_attributes(transform
, expect_transform_attributes
, FALSE
);
2120 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2121 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2123 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2124 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2127 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2129 winetest_push_context("in %lu", i
);
2130 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2131 check_media_type(media_type
, expect_input_attributes
, -1);
2132 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2133 ret
= IMFMediaType_Release(media_type
);
2134 ok(ret
<= 1, "Release returned %lu\n", ret
);
2135 winetest_pop_context();
2137 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
2138 ok(i
== ARRAY_SIZE(expect_available_inputs
)
2139 || broken(i
== 2) /* w7 */ || broken(i
== 4) /* w8 */,
2140 "%lu input media types\n", i
);
2142 /* setting output media type first doesn't work */
2143 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
2144 check_mft_get_output_current_type(transform
, NULL
);
2146 check_mft_set_input_type_required(transform
, input_type_desc
);
2147 check_mft_set_input_type(transform
, input_type_desc
);
2148 check_mft_get_input_current_type(transform
, input_type_desc
);
2150 /* check new output media types */
2153 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
2155 winetest_push_context("out %lu", i
);
2156 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
2157 check_media_type(media_type
, expect_output_attributes
, -1);
2158 check_media_type(media_type
, expect_available_outputs
[i
], -1);
2159 ret
= IMFMediaType_Release(media_type
);
2160 ok(ret
<= 1, "Release returned %lu\n", ret
);
2161 winetest_pop_context();
2163 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
2164 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
2166 check_mft_set_output_type_required(transform
, output_type_desc
);
2167 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2168 check_mft_get_output_current_type(transform
, output_type_desc
);
2170 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2171 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2173 load_resource(L
"aacencdata.bin", &aacenc_data
, &aacenc_data_len
);
2174 ok(aacenc_data_len
== 24861, "got length %lu\n", aacenc_data_len
);
2176 input_sample
= create_sample(aacenc_data
+ sizeof(DWORD
), *(DWORD
*)aacenc_data
);
2177 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2178 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2179 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2180 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2182 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2183 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2185 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2186 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
2187 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2188 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2189 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2191 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2192 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2193 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2194 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2196 hr
= MFCreateCollection(&output_samples
);
2197 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2199 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2200 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2202 winetest_push_context("%lu", i
);
2203 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2204 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2205 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2206 ref
= IMFSample_Release(output_sample
);
2207 ok(ref
== 1, "Release returned %ld\n", ref
);
2208 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2209 winetest_pop_context();
2211 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2212 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2213 ret
= IMFSample_Release(output_sample
);
2214 ok(ret
== 0, "Release returned %lu\n", ret
);
2215 ok(i
== 1, "got %lu output samples\n", i
);
2217 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacdecdata.bin");
2218 todo_wine_if(ret
<= 5)
2219 ok(ret
== 0, "got %lu%% diff\n", ret
);
2220 IMFCollection_Release(output_samples
);
2222 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2223 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2224 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2225 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2226 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2227 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2228 ok(length
== 0, "got length %lu\n", length
);
2229 ret
= IMFSample_Release(output_sample
);
2230 ok(ret
== 0, "Release returned %lu\n", ret
);
2232 ret
= IMFSample_Release(input_sample
);
2233 ok(ret
== 0, "Release returned %lu\n", ret
);
2234 ret
= IMFTransform_Release(transform
);
2235 ok(ret
== 0, "Release returned %lu\n", ret
);
2238 winetest_pop_context();
2242 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
2243 static const ULONG wmaenc_block_size
= 1487;
2244 static const ULONG wmadec_block_size
= 0x2000;
2246 static void test_wma_encoder(void)
2248 const GUID
*const class_id
= &CLSID_CWMAEncMediaObject
;
2249 const struct transform_info expect_mft_info
=
2251 .name
= L
"WMAudio Encoder MFT",
2252 .major_type
= &MFMediaType_Audio
,
2255 {.subtype
= &MFAudioFormat_PCM
},
2256 {.subtype
= &MFAudioFormat_Float
},
2260 {.subtype
= &MFAudioFormat_WMAudioV8
},
2261 {.subtype
= &MFAudioFormat_WMAudioV9
},
2262 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2265 const struct transform_info expect_dmo_info
=
2267 .name
= L
"WMAudio Encoder DMO",
2268 .major_type
= &MEDIATYPE_Audio
,
2271 {.subtype
= &MEDIASUBTYPE_PCM
},
2275 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2276 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2277 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2281 static const struct attribute_desc input_type_desc
[] =
2283 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2284 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
2285 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2286 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
2287 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2288 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
2289 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
2292 const struct attribute_desc output_type_desc
[] =
2294 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2295 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2296 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2297 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2298 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003, .required
= TRUE
),
2299 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2300 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2303 static const struct attribute_desc expect_input_type_desc
[] =
2305 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2306 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2307 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2308 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2309 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2310 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2311 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
2312 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
2313 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2316 const struct attribute_desc expect_output_type_desc
[] =
2318 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2319 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2320 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2321 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2322 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2323 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2324 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2325 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2328 const MFT_OUTPUT_STREAM_INFO output_info
=
2330 .cbSize
= wmaenc_block_size
,
2333 const MFT_INPUT_STREAM_INFO input_info
=
2335 .hnsMaxLatency
= 19969161,
2340 const struct buffer_desc output_buffer_desc
[] =
2342 {.length
= wmaenc_block_size
},
2344 const struct attribute_desc output_sample_attributes
[] =
2346 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2347 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2350 const struct sample_desc output_sample_desc
[] =
2353 .attributes
= output_sample_attributes
,
2354 .sample_time
= 0, .sample_duration
= 3250794,
2355 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2358 .attributes
= output_sample_attributes
,
2359 .sample_time
= 3250794, .sample_duration
= 3715193,
2360 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2363 .attributes
= output_sample_attributes
,
2364 .sample_time
= 6965986, .sample_duration
= 3366893,
2365 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2369 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2370 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2371 IMFSample
*input_sample
, *output_sample
;
2372 IMFCollection
*output_samples
;
2373 DWORD length
, output_status
;
2374 IMFMediaType
*media_type
;
2375 IMFTransform
*transform
;
2376 const BYTE
*audio_data
;
2377 ULONG audio_data_len
;
2382 hr
= CoInitialize(NULL
);
2383 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2385 winetest_push_context("wmaenc");
2387 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2389 check_mft_get_info(class_id
, &expect_mft_info
);
2390 check_dmo_get_info(class_id
, &expect_dmo_info
);
2392 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2393 &IID_IMFTransform
, (void **)&transform
)))
2396 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2397 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2398 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2399 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2401 check_mft_optional_methods(transform
, 1);
2402 check_mft_get_attributes(transform
, NULL
, FALSE
);
2403 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2404 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2406 check_mft_set_input_type_required(transform
, input_type_desc
);
2408 hr
= MFCreateMediaType(&media_type
);
2409 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
2410 init_media_type(media_type
, input_type_desc
, -1);
2411 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
2412 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
2413 ret
= IMFMediaType_Release(media_type
);
2414 ok(ret
== 0, "Release returned %lu\n", ret
);
2416 check_mft_set_output_type_required(transform
, output_type_desc
);
2417 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2418 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2420 check_mft_set_input_type_required(transform
, input_type_desc
);
2421 check_mft_set_input_type(transform
, input_type_desc
);
2422 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2424 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2425 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2427 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2428 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2430 input_sample
= create_sample(audio_data
, audio_data_len
);
2431 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2432 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2433 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2434 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2435 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2436 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2437 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2438 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2439 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2440 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2441 ref
= IMFSample_Release(input_sample
);
2442 ok(ref
<= 1, "Release returned %ld\n", ref
);
2444 hr
= MFCreateCollection(&output_samples
);
2445 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2447 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2448 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2450 winetest_push_context("%lu", i
);
2451 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2452 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
2453 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2454 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2455 ref
= IMFSample_Release(output_sample
);
2456 ok(ref
== 1, "Release returned %ld\n", ref
);
2457 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2458 winetest_pop_context();
2460 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2461 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2462 ret
= IMFSample_Release(output_sample
);
2463 ok(ret
== 0, "Release returned %lu\n", ret
);
2464 ok(i
== 3, "got %lu output samples\n", i
);
2466 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmaencdata.bin");
2467 ok(ret
== 0, "got %lu%% diff\n", ret
);
2468 IMFCollection_Release(output_samples
);
2470 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2471 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2472 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2473 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2474 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2475 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2476 ok(length
== 0, "got length %lu\n", length
);
2477 ret
= IMFSample_Release(output_sample
);
2478 ok(ret
== 0, "Release returned %lu\n", ret
);
2480 ret
= IMFTransform_Release(transform
);
2481 ok(ret
== 0, "Release returned %lu\n", ret
);
2484 winetest_pop_context();
2488 static void test_wma_decoder(void)
2490 const GUID
*const class_id
= &CLSID_CWMADecMediaObject
;
2491 const struct transform_info expect_mft_info
=
2493 .name
= L
"WMAudio Decoder MFT",
2494 .major_type
= &MFMediaType_Audio
,
2497 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2498 {.subtype
= &MFAudioFormat_WMAudioV8
},
2499 {.subtype
= &MFAudioFormat_WMAudioV9
},
2500 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2504 {.subtype
= &MFAudioFormat_PCM
},
2505 {.subtype
= &MFAudioFormat_Float
},
2508 const struct transform_info expect_dmo_info
=
2510 .name
= L
"WMAudio Decoder DMO",
2511 .major_type
= &MEDIATYPE_Audio
,
2514 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2515 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2516 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2517 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2521 {.subtype
= &MEDIASUBTYPE_PCM
},
2522 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
2526 static const media_type_desc expect_available_inputs
[] =
2529 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2530 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
2531 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2534 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2535 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2536 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2539 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2540 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
2541 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2544 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2545 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
2546 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2549 static const media_type_desc expect_available_outputs
[] =
2552 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2553 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2554 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2555 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2556 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2557 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
2558 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2559 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2560 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2561 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2564 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2565 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2566 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2567 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2568 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2569 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
2570 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2571 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2572 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2573 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2577 const struct attribute_desc input_type_desc
[] =
2579 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2580 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2581 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2582 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2583 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2584 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2585 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003), /* not required by SetInputType, but needed for the transform to work */
2588 static const struct attribute_desc output_type_desc
[] =
2590 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2591 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2592 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2593 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2594 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2595 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
2596 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
2599 const struct attribute_desc expect_input_type_desc
[] =
2601 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2602 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2603 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2604 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2605 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2606 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2607 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2608 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2611 static const struct attribute_desc expect_output_type_desc
[] =
2613 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2614 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2615 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
2616 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2617 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2618 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2619 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2620 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2621 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2624 const MFT_INPUT_STREAM_INFO input_info
=
2626 .cbSize
= wmaenc_block_size
,
2629 const MFT_OUTPUT_STREAM_INFO output_info
=
2631 .cbSize
= wmadec_block_size
,
2635 const struct buffer_desc output_buffer_desc
[] =
2637 {.length
= wmadec_block_size
, .compare
= compare_pcm16
},
2638 {.length
= wmadec_block_size
/ 2, .compare
= compare_pcm16
, .todo_length
= TRUE
},
2640 const struct attribute_desc output_sample_attributes
[] =
2642 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2643 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2646 const struct attribute_desc output_sample_attributes_todo
[] =
2648 ATTR_UINT32(mft_output_sample_incomplete
, 1, .todo
= TRUE
),
2649 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2652 struct sample_desc output_sample_desc
[] =
2655 .attributes
= output_sample_attributes
+ 0,
2656 .sample_time
= 0, .sample_duration
= 928798,
2657 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 1,
2660 .attributes
= output_sample_attributes
+ 0,
2661 .sample_time
= 1857596, .sample_duration
= 928798,
2662 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
2665 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
2666 .sample_time
= 2786394, .sample_duration
= 464399,
2667 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
2671 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2672 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2673 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
2674 IMFSample
*input_sample
, *output_sample
;
2675 IMFCollection
*output_samples
;
2676 DWORD length
, output_status
;
2677 IMediaObject
*media_object
;
2678 IPropertyBag
*property_bag
;
2679 IMFMediaType
*media_type
;
2680 IMFTransform
*transform
;
2681 const BYTE
*wmaenc_data
;
2682 ULONG wmaenc_data_len
;
2686 hr
= CoInitialize(NULL
);
2687 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2689 winetest_push_context("wmadec");
2691 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2693 check_mft_get_info(class_id
, &expect_mft_info
);
2694 check_dmo_get_info(class_id
, &expect_dmo_info
);
2696 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2697 &IID_IMFTransform
, (void **)&transform
)))
2700 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2701 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2703 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2704 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2706 check_mft_optional_methods(transform
, 1);
2707 check_mft_get_attributes(transform
, NULL
, FALSE
);
2708 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2709 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2711 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2712 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2715 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2717 winetest_push_context("in %lu", i
);
2718 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2719 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2720 ret
= IMFMediaType_Release(media_type
);
2721 ok(ret
== 0, "Release returned %lu\n", ret
);
2722 winetest_pop_context();
2725 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
2727 ok(i
== 4, "%lu input media types\n", i
);
2729 /* setting output media type first doesn't work */
2730 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
2731 check_mft_get_output_current_type_(transform
, NULL
, TRUE
, FALSE
);
2733 check_mft_set_input_type_required(transform
, input_type_desc
);
2734 check_mft_set_input_type(transform
, input_type_desc
);
2735 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
2737 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2738 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2740 /* check new output media types */
2743 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
2745 winetest_push_context("out %lu", i
);
2746 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
2747 check_media_type(media_type
, expect_available_outputs
[i
], -1);
2748 ret
= IMFMediaType_Release(media_type
);
2749 ok(ret
== 0, "Release returned %lu\n", ret
);
2750 winetest_pop_context();
2752 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
2753 ok(i
== 2, "%lu output media types\n", i
);
2755 check_mft_set_output_type_required(transform
, output_type_desc
);
2756 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2757 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, TRUE
, FALSE
);
2759 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2760 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2762 load_resource(L
"wmaencdata.bin", &wmaenc_data
, &wmaenc_data_len
);
2763 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
2765 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
2766 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2767 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2768 ret
= IMFSample_Release(input_sample
);
2769 ok(ret
== 0, "Release returned %lu\n", ret
);
2770 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
2771 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2772 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2773 ret
= IMFSample_Release(input_sample
);
2774 ok(ret
== 0, "Release returned %lu\n", ret
);
2775 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2776 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2777 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2778 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2779 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2780 ret
= IMFSample_Release(input_sample
);
2781 ok(ret
== 1, "Release returned %lu\n", ret
);
2783 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2784 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2786 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2787 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2788 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
2789 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
2790 "got output[0].dwStatus %#lx\n", output_status
);
2792 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2793 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2794 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2795 ret
= IMFSample_Release(input_sample
);
2796 ok(ret
== 0, "Release returned %lu\n", ret
);
2798 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2799 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2800 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
2801 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
2802 "got output[0].dwStatus %#lx\n", output_status
);
2804 hr
= MFCreateCollection(&output_samples
);
2805 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2807 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2808 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2810 winetest_push_context("%lu", i
);
2811 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
2812 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2813 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2814 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2815 ref
= IMFSample_Release(output_sample
);
2816 ok(ref
== 1, "Release returned %ld\n", ref
);
2817 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2818 winetest_pop_context();
2820 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2821 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2822 ret
= IMFSample_Release(output_sample
);
2823 ok(ret
== 0, "Release returned %lu\n", ret
);
2824 todo_wine_if(i
== 3) /* wmadec output depends on ffmpeg version used */
2825 ok(i
== 4, "got %lu output samples\n", i
);
2827 if (!strcmp(winetest_platform
, "wine") && i
== 3)
2828 output_sample_desc
[1].attributes
= output_sample_attributes_todo
;
2830 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmadecdata.bin");
2831 todo_wine_if(ret
> 0 && ret
<= 10) /* ffmpeg sometimes offsets the decoded data */
2832 ok(ret
== 0, "got %lu%% diff\n", ret
);
2833 IMFCollection_Release(output_samples
);
2835 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2836 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2837 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2838 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2839 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2840 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2841 ok(length
== 0, "got length %lu\n", length
);
2842 ret
= IMFSample_Release(output_sample
);
2843 ok(ret
== 0, "Release returned %lu\n", ret
);
2845 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
2846 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2847 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2849 ret
= IMFTransform_Release(transform
);
2850 ok(ret
== 0, "Release returned %lu\n", ret
);
2851 ret
= IMFSample_Release(input_sample
);
2852 ok(ret
== 0, "Release returned %lu\n", ret
);
2854 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
2855 (void **)&unknown
);
2856 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
2857 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
2858 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2859 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
2860 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2861 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
2862 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2863 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
2864 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
2866 ok( unknown
!= &outer
, "got outer IUnknown\n" );
2867 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
2868 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
2869 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
2870 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
2872 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
2873 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
2874 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
2875 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
2876 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
2877 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
2879 ref
= IUnknown_Release( tmp_unknown
);
2880 ok( ref
== 1, "Release returned %lu\n", ref
);
2881 ref
= IPropertyBag_Release( property_bag
);
2882 ok( ref
== 1, "Release returned %lu\n", ref
);
2883 ref
= IMediaObject_Release( media_object
);
2884 ok( ref
== 1, "Release returned %lu\n", ref
);
2885 ref
= IMFTransform_Release( transform
);
2886 ok( ref
== 1, "Release returned %lu\n", ref
);
2887 ref
= IUnknown_Release( unknown
);
2888 ok( ref
== 0, "Release returned %lu\n", ref
);
2891 winetest_pop_context();
2895 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
2896 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
2898 const BYTE
*sample_data
;
2900 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
2901 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
2902 sample_data
= *h264_buf
;
2907 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
2913 return create_sample(sample_data
, *h264_buf
- sample_data
);
2916 static void test_h264_decoder(void)
2918 const GUID
*const class_id
= &CLSID_MSH264DecoderMFT
;
2919 const struct transform_info expect_mft_info
=
2921 .name
= L
"Microsoft H264 Video Decoder MFT",
2922 .major_type
= &MFMediaType_Video
,
2925 {.subtype
= &MFVideoFormat_H264
},
2926 {.subtype
= &MFVideoFormat_H264_ES
},
2930 {.subtype
= &MFVideoFormat_NV12
},
2931 {.subtype
= &MFVideoFormat_YV12
},
2932 {.subtype
= &MFVideoFormat_IYUV
},
2933 {.subtype
= &MFVideoFormat_I420
},
2934 {.subtype
= &MFVideoFormat_YUY2
},
2937 static const media_type_desc default_inputs
[] =
2940 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2941 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
2944 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2945 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
2948 static const struct attribute_desc expect_transform_attributes
[] =
2950 ATTR_UINT32(MF_LOW_LATENCY
, 0),
2951 ATTR_UINT32(MF_SA_D3D_AWARE
, 1, .todo
= TRUE
),
2952 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1, .todo
= TRUE
),
2953 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0, .todo
= TRUE
),
2954 /* more H264 decoder specific attributes from CODECAPI */
2957 static const DWORD input_width
= 120, input_height
= 248;
2958 const media_type_desc default_outputs
[] =
2961 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2962 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
2963 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2964 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2965 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2966 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2967 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2968 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2969 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2970 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2971 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2974 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2975 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
2976 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2977 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2978 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2979 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2980 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2981 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2982 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2983 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2984 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
2987 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
2988 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
2989 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
2990 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
2991 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
2992 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
2993 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2994 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2995 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
2996 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
2997 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3000 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3001 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3002 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3003 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3004 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3005 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3006 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3007 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3008 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3009 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3010 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3013 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3014 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3015 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3016 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3017 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
* 2),
3018 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3019 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3020 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3021 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3022 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 2),
3023 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3026 const struct attribute_desc input_type_desc
[] =
3028 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3029 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
, .required
= TRUE
),
3030 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3033 const struct attribute_desc output_type_desc
[] =
3035 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3036 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
3037 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
, .required
= TRUE
),
3038 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3039 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3040 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3041 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3042 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3045 const struct attribute_desc expect_input_type_desc
[] =
3047 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3048 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
3049 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3050 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 0),
3051 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 0),
3052 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
3053 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3054 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
3057 const struct attribute_desc expect_output_type_desc
[] =
3059 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3060 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3061 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3062 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3063 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3064 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3065 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3066 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3067 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3068 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3071 static const struct attribute_desc new_output_type_desc
[] =
3073 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3074 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3075 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3076 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3077 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3080 static const struct attribute_desc expect_new_output_type_desc
[] =
3082 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3083 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3084 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3085 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3086 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3087 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3088 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3091 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
3092 static const DWORD actual_width
= 96, actual_height
= 96;
3093 const media_type_desc actual_outputs
[] =
3096 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3097 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3098 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3099 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3100 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3101 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3102 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3103 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3104 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3105 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3106 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3107 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3110 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3111 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3112 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3113 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3114 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3115 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3116 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3117 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3118 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3119 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3120 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3121 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3124 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3125 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3126 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3127 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3128 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3129 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3130 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3131 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3132 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3133 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3134 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3135 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3138 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3139 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3140 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3141 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3142 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3143 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3144 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3145 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3146 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3147 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3148 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3149 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3152 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3153 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3154 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3155 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3156 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3157 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3158 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3159 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3160 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3161 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3162 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3163 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3166 const MFT_OUTPUT_STREAM_INFO initial_output_info
=
3168 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3169 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3170 .cbSize
= 1920 * 1088 * 2,
3172 const MFT_OUTPUT_STREAM_INFO output_info
=
3174 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3175 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3176 .cbSize
= input_width
* input_height
* 2,
3178 const MFT_OUTPUT_STREAM_INFO actual_output_info
=
3180 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3181 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3182 .cbSize
= actual_width
* actual_height
* 2,
3184 const MFT_INPUT_STREAM_INFO input_info
=
3186 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3187 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
,
3191 const struct attribute_desc output_sample_attributes
[] =
3193 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3196 const struct buffer_desc output_buffer_desc_nv12
=
3198 .length
= actual_width
* actual_height
* 3 / 2,
3199 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
3201 const struct sample_desc output_sample_desc_nv12
=
3203 .attributes
= output_sample_attributes
,
3204 .sample_time
= 0, .sample_duration
= 333667,
3205 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
3207 const struct buffer_desc output_buffer_desc_i420
=
3209 .length
= actual_width
* actual_height
* 3 / 2,
3210 .compare
= compare_i420
, .dump
= dump_i420
, .rect
= {.right
= 82, .bottom
= 84},
3212 const struct sample_desc expect_output_sample_i420
=
3214 .attributes
= output_sample_attributes
,
3215 .sample_time
= 333667, .sample_duration
= 333667, .todo_time
= 1334666 /* with VA-API */,
3216 .buffer_count
= 1, .buffers
= &output_buffer_desc_i420
,
3219 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
3220 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3221 IMFSample
*input_sample
, *output_sample
;
3222 const BYTE
*h264_encoded_data
;
3223 IMFCollection
*output_samples
;
3224 ULONG h264_encoded_data_len
;
3225 DWORD length
, output_status
;
3226 IMFAttributes
*attributes
;
3227 IMFMediaType
*media_type
;
3228 IMFTransform
*transform
;
3232 hr
= CoInitialize(NULL
);
3233 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3235 winetest_push_context("h264dec");
3237 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
3239 check_mft_get_info(class_id
, &expect_mft_info
);
3241 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3242 &IID_IMFTransform
, (void **)&transform
)))
3245 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3246 check_interface(transform
, &IID_IMediaObject
, FALSE
);
3247 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
3248 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
3250 check_mft_optional_methods(transform
, 1);
3251 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
3252 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3253 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
3255 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3256 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
3257 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
3258 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
3259 IMFAttributes_Release(attributes
);
3261 /* no output type is available before an input type is set */
3263 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3264 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3266 /* setting output media type first doesn't work */
3267 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3268 check_mft_get_output_current_type(transform
, NULL
);
3270 /* check available input types */
3273 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3275 winetest_push_context("in %lu", i
);
3276 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3277 check_media_type(media_type
, default_inputs
[i
], -1);
3278 ret
= IMFMediaType_Release(media_type
);
3279 ok(ret
== 0, "Release returned %lu\n", ret
);
3280 winetest_pop_context();
3282 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3283 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
3285 check_mft_set_input_type_required(transform
, input_type_desc
);
3286 check_mft_set_input_type(transform
, input_type_desc
);
3287 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3289 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3290 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3292 /* output types can now be enumerated (though they are actually the same for all input types) */
3295 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3297 winetest_push_context("out %lu", i
);
3298 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3299 check_media_type(media_type
, default_outputs
[i
], -1);
3300 ret
= IMFMediaType_Release(media_type
);
3301 ok(ret
== 0, "Release returned %lu\n", ret
);
3302 winetest_pop_context();
3304 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3305 ok(i
== 5, "%lu output media types\n", i
);
3307 check_mft_set_output_type_required(transform
, output_type_desc
);
3308 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3309 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3311 /* check that the output media type we've selected don't change the enumeration */
3314 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3316 winetest_push_context("out %lu", i
);
3317 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3318 check_media_type(media_type
, default_outputs
[i
], -1);
3319 ret
= IMFMediaType_Release(media_type
);
3320 ok(ret
== 0, "Release returned %lu\n", ret
);
3321 winetest_pop_context();
3323 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3324 ok(i
== 5, "%lu output media types\n", i
);
3326 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3327 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3329 load_resource(L
"h264data.bin", &h264_encoded_data
, &h264_encoded_data_len
);
3331 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3332 * IMFTransform_ProcessOutput needs a sample or returns an error */
3334 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3335 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3336 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3339 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3342 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3343 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3344 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
3346 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3347 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3348 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3349 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3350 ok(length
== 0, "got length %lu\n", length
);
3351 ret
= IMFSample_Release(output_sample
);
3352 ok(ret
== 0, "Release returned %lu\n", ret
);
3354 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3355 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3356 ret
= IMFSample_Release(input_sample
);
3357 ok(ret
<= 1, "Release returned %lu\n", ret
);
3358 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3360 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3361 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3362 ret
= IMFSample_Release(input_sample
);
3363 ok(ret
<= 1, "Release returned %lu\n", ret
);
3364 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3367 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3368 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3371 ok(i
== 2, "got %lu iterations\n", i
);
3373 ok(h264_encoded_data_len
== 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
3374 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3375 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3376 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3377 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3378 ok(length
== 0, "got length %lu\n", length
);
3379 ret
= IMFSample_Release(output_sample
);
3380 ok(ret
== 0, "Release returned %lu\n", ret
);
3382 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3383 check_mft_get_output_stream_info(transform
, S_OK
, &actual_output_info
);
3386 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3388 winetest_push_context("out %lu", i
);
3389 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3390 check_media_type(media_type
, actual_outputs
[i
], -1);
3391 ret
= IMFMediaType_Release(media_type
);
3392 ok(ret
== 0, "Release returned %lu\n", ret
);
3393 winetest_pop_context();
3395 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3396 ok(i
== 5, "%lu output media types\n", i
);
3398 /* current output type is still the one we selected */
3399 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3401 hr
= MFCreateCollection(&output_samples
);
3402 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3404 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3405 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3406 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3407 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3408 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3409 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3410 ref
= IMFSample_Release(output_sample
);
3411 ok(ref
== 1, "Release returned %ld\n", ref
);
3413 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
3414 ok(ret
== 0, "got %lu%% diff\n", ret
);
3415 IMFCollection_Release(output_samples
);
3417 /* we can change it, but only with the correct frame size */
3418 hr
= MFCreateMediaType(&media_type
);
3419 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
3420 init_media_type(media_type
, output_type_desc
, -1);
3421 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3422 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
3423 init_media_type(media_type
, new_output_type_desc
, -1);
3424 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3425 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
3426 ret
= IMFMediaType_Release(media_type
);
3427 ok(ret
== 1, "Release returned %lu\n", ret
);
3429 check_mft_get_output_current_type_(transform
, expect_new_output_type_desc
, FALSE
, TRUE
);
3431 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3432 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3434 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3436 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3438 while (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
3440 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3441 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3442 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3443 ret
= IMFSample_Release(input_sample
);
3444 ok(ret
<= 1, "Release returned %lu\n", ret
);
3445 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3446 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3449 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3450 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3452 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3453 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3454 ok(length
== 0, "got length %lu\n", length
);
3455 ret
= IMFSample_Release(output_sample
);
3456 ok(ret
== 0, "Release returned %lu\n", ret
);
3458 hr
= MFCreateCollection(&output_samples
);
3459 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3461 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3462 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3463 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3464 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3465 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3466 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3467 ref
= IMFSample_Release(output_sample
);
3468 ok(ref
== 1, "Release returned %ld\n", ref
);
3470 ret
= check_mf_sample_collection(output_samples
, &expect_output_sample_i420
, L
"i420frame.bmp");
3471 ok(ret
== 0, "got %lu%% diff\n", ret
);
3472 IMFCollection_Release(output_samples
);
3474 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3475 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3476 todo_wine_if(hr
== S_OK
) /* when VA-API plugin is used */
3477 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3478 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3479 ret
= IMFSample_Release(output_sample
);
3480 ok(ret
== 0, "Release returned %lu\n", ret
);
3482 ret
= IMFTransform_Release(transform
);
3483 ok(ret
== 0, "Release returned %lu\n", ret
);
3484 ret
= IMFSample_Release(input_sample
);
3485 ok(ret
== 0, "Release returned %lu\n", ret
);
3488 winetest_pop_context();
3492 static void test_audio_convert(void)
3494 const GUID
*const class_id
= &CLSID_CResamplerMediaObject
;
3495 const struct transform_info expect_mft_info
=
3497 .name
= L
"Resampler MFT",
3498 .major_type
= &MFMediaType_Audio
,
3501 {.subtype
= &MFAudioFormat_PCM
},
3502 {.subtype
= &MFAudioFormat_Float
},
3506 {.subtype
= &MFAudioFormat_PCM
},
3507 {.subtype
= &MFAudioFormat_Float
},
3510 const struct transform_info expect_dmo_info
=
3512 .name
= L
"Resampler DMO",
3513 .major_type
= &MEDIATYPE_Audio
,
3516 {.subtype
= &MEDIASUBTYPE_PCM
},
3517 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3521 {.subtype
= &MEDIASUBTYPE_PCM
},
3522 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3526 static const media_type_desc expect_available_inputs
[] =
3529 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3530 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3531 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3534 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3535 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3536 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3539 static const media_type_desc expect_available_outputs
[] =
3542 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3543 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3544 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3547 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3548 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3549 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3552 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3553 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3554 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3555 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3556 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3557 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
3558 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3559 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3560 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3563 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3564 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3565 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3566 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3567 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3568 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
3569 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3570 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3571 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3575 static const struct attribute_desc input_type_desc
[] =
3577 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3578 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
3579 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3580 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
3581 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
3582 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
3583 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
3586 const struct attribute_desc output_type_desc
[] =
3588 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3589 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
3590 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3591 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
3592 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
3593 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
3594 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 44100, .required
= TRUE
),
3597 static const struct attribute_desc expect_input_type_desc
[] =
3599 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3600 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3601 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3602 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3603 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3604 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3605 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
3606 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3607 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
3610 const struct attribute_desc expect_output_type_desc
[] =
3612 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3613 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3614 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3615 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3616 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
3617 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3618 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 4),
3619 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3620 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3623 const MFT_OUTPUT_STREAM_INFO output_info
=
3628 const MFT_INPUT_STREAM_INFO input_info
=
3634 static const ULONG audioconv_block_size
= 0x4000;
3635 const struct buffer_desc output_buffer_desc
[] =
3637 {.length
= audioconv_block_size
, .compare
= compare_pcm16
},
3638 {.length
= 0x3dd8, .compare
= compare_pcm16
, .todo_length
= TRUE
},
3639 {.length
= 0xfc, .compare
= compare_pcm16
},
3641 const struct attribute_desc output_sample_attributes
[] =
3643 ATTR_UINT32(mft_output_sample_incomplete
, 1),
3644 ATTR_UINT32(MFSampleExtension_CleanPoint
, has_video_processor
/* 0 on Win7 */, .todo
= TRUE
),
3647 const struct sample_desc output_sample_desc
[] =
3650 .attributes
= output_sample_attributes
+ 0,
3651 .sample_time
= 0, .sample_duration
= 928798,
3652 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 9,
3655 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
3656 .sample_time
= 9287980, .sample_duration
= 897506,
3657 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
3660 .attributes
= output_sample_attributes
+ 0,
3661 .sample_time
= 10185486, .sample_duration
= 14286,
3662 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 2,
3666 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
3667 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
3668 IMFSample
*input_sample
, *output_sample
;
3669 IMFCollection
*output_samples
;
3670 DWORD length
, output_status
;
3671 IMFMediaType
*media_type
;
3672 IMFTransform
*transform
;
3673 const BYTE
*audio_data
;
3674 ULONG audio_data_len
;
3678 hr
= CoInitialize(NULL
);
3679 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3681 winetest_push_context("resampler");
3683 if (!check_mft_enum(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, class_id
))
3685 check_mft_get_info(class_id
, &expect_mft_info
);
3686 check_dmo_get_info(class_id
, &expect_dmo_info
);
3688 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3689 &IID_IMFTransform
, (void **)&transform
)))
3692 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3693 check_interface(transform
, &IID_IMediaObject
, TRUE
);
3694 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
3695 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
3696 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
3698 check_mft_optional_methods(transform
, 1);
3699 check_mft_get_attributes(transform
, NULL
, FALSE
);
3700 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3701 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3704 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3706 winetest_push_context("out %lu", i
);
3707 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3708 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3709 ret
= IMFMediaType_Release(media_type
);
3710 ok(ret
== 0, "Release returned %lu\n", ret
);
3711 winetest_pop_context();
3713 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3714 ok(i
== 4, "%lu output media types\n", i
);
3717 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3719 winetest_push_context("in %lu", i
);
3720 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3721 check_media_type(media_type
, expect_available_inputs
[i
], -1);
3722 ret
= IMFMediaType_Release(media_type
);
3723 ok(ret
== 0, "Release returned %lu\n", ret
);
3724 winetest_pop_context();
3726 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3727 ok(i
== 2, "%lu input media types\n", i
);
3729 /* setting output media type first doesn't work */
3730 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3731 check_mft_get_output_current_type(transform
, NULL
);
3733 check_mft_set_input_type_required(transform
, input_type_desc
);
3734 check_mft_set_input_type(transform
, input_type_desc
);
3735 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
3737 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3738 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3740 /* check new output media types */
3743 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3745 winetest_push_context("out %lu", i
);
3746 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3747 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3748 ret
= IMFMediaType_Release(media_type
);
3749 ok(ret
== 0, "Release returned %lu\n", ret
);
3750 winetest_pop_context();
3752 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3753 ok(i
== 4, "%lu output media types\n", i
);
3755 check_mft_set_output_type_required(transform
, output_type_desc
);
3756 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3757 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3759 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3760 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3762 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
3763 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
3765 input_sample
= create_sample(audio_data
, audio_data_len
);
3766 hr
= IMFSample_SetSampleTime(input_sample
, 0);
3767 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
3768 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
3769 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
3770 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3771 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3772 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3773 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3774 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3775 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3776 ret
= IMFSample_Release(input_sample
);
3777 ok(ret
<= 1, "Release returned %ld\n", ret
);
3779 hr
= MFCreateCollection(&output_samples
);
3780 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3782 output_sample
= create_sample(NULL
, audioconv_block_size
);
3783 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
3785 winetest_push_context("%lu", i
);
3786 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3787 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
3788 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3789 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3790 ref
= IMFSample_Release(output_sample
);
3791 ok(ref
== 1, "Release returned %ld\n", ref
);
3792 output_sample
= create_sample(NULL
, audioconv_block_size
);
3793 winetest_pop_context();
3795 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3796 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3797 ret
= IMFSample_Release(output_sample
);
3798 ok(ret
== 0, "Release returned %lu\n", ret
);
3800 ok(i
== 12 || broken(i
== 11) /* Win7 */, "got %lu output samples\n", i
);
3802 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"audioconvdata.bin");
3803 ok(ret
== 0, "got %lu%% diff\n", ret
);
3804 IMFCollection_Release(output_samples
);
3806 output_sample
= create_sample(NULL
, audioconv_block_size
);
3807 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3808 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3809 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3810 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3811 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3812 ok(length
== 0, "got length %lu\n", length
);
3813 ret
= IMFSample_Release(output_sample
);
3814 ok(ret
== 0, "Release returned %lu\n", ret
);
3816 ret
= IMFTransform_Release(transform
);
3817 ok(ret
== 0, "Release returned %lu\n", ret
);
3820 winetest_pop_context();
3824 static void test_wmv_encoder(void)
3826 const GUID
*const class_id
= &CLSID_CWMVXEncMediaObject
;
3827 const struct transform_info expect_mft_info
=
3829 .name
= L
"WMVideo8 Encoder MFT",
3830 .major_type
= &MFMediaType_Video
,
3833 {.subtype
= &MFVideoFormat_IYUV
},
3834 {.subtype
= &MFVideoFormat_I420
},
3835 {.subtype
= &MFVideoFormat_YV12
},
3836 {.subtype
= &MFVideoFormat_NV11
},
3837 {.subtype
= &MFVideoFormat_NV12
},
3838 {.subtype
= &MFVideoFormat_YUY2
},
3839 {.subtype
= &MFVideoFormat_UYVY
},
3840 {.subtype
= &MFVideoFormat_YVYU
},
3841 {.subtype
= &MFVideoFormat_YVU9
},
3842 {.subtype
= &DMOVideoFormat_RGB32
},
3843 {.subtype
= &DMOVideoFormat_RGB24
},
3844 {.subtype
= &DMOVideoFormat_RGB565
},
3845 {.subtype
= &DMOVideoFormat_RGB555
},
3846 {.subtype
= &DMOVideoFormat_RGB8
},
3850 {.subtype
= &MFVideoFormat_WMV1
},
3851 {.subtype
= &MFVideoFormat_WMV2
},
3854 const struct transform_info expect_dmo_info
=
3856 .name
= L
"WMVideo8 Encoder DMO",
3857 .major_type
= &MEDIATYPE_Video
,
3860 {.subtype
= &MEDIASUBTYPE_IYUV
},
3861 {.subtype
= &MEDIASUBTYPE_I420
},
3862 {.subtype
= &MEDIASUBTYPE_YV12
},
3863 {.subtype
= &MEDIASUBTYPE_NV11
},
3864 {.subtype
= &MEDIASUBTYPE_NV12
},
3865 {.subtype
= &MEDIASUBTYPE_YUY2
},
3866 {.subtype
= &MEDIASUBTYPE_UYVY
},
3867 {.subtype
= &MEDIASUBTYPE_YVYU
},
3868 {.subtype
= &MEDIASUBTYPE_YVU9
},
3869 {.subtype
= &MEDIASUBTYPE_RGB32
},
3870 {.subtype
= &MEDIASUBTYPE_RGB24
},
3871 {.subtype
= &MEDIASUBTYPE_RGB565
},
3872 {.subtype
= &MEDIASUBTYPE_RGB555
},
3873 {.subtype
= &MEDIASUBTYPE_RGB8
},
3877 {.subtype
= &MEDIASUBTYPE_WMV1
},
3878 {.subtype
= &MEDIASUBTYPE_WMV2
},
3882 static const media_type_desc expect_available_inputs
[] =
3885 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3886 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3887 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3888 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3889 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3890 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3891 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3892 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3895 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3896 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3897 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3898 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3899 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3900 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3901 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3902 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3905 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3906 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3907 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3908 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3909 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3910 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3911 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3912 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3915 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3916 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
3917 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3918 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3919 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3920 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3921 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3922 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3925 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3926 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3927 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3928 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3929 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3930 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3931 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3932 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3935 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3936 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3937 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3938 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3939 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3940 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3941 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3942 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3945 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3946 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
3947 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3948 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3949 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3950 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3951 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3952 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3955 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3956 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
3957 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3958 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3959 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3960 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3961 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3962 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3965 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3966 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
3967 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3968 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3969 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3970 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3971 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3972 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3975 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3976 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
3977 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3978 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3979 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3980 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3981 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3982 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3985 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3986 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
3987 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3988 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3989 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3990 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
3991 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
3992 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
3995 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3996 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
3997 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3998 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3999 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4000 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4001 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4002 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4005 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4006 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
),
4007 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4008 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4009 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4010 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4011 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4012 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4015 static const media_type_desc expect_available_outputs
[] =
4018 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4019 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4020 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4021 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4022 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4023 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4026 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4027 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
),
4028 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4029 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4030 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4031 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4035 static const DWORD actual_width
= 96, actual_height
= 96;
4036 const struct attribute_desc input_type_desc
[] =
4038 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4039 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4040 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4041 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
), /* required for SetOutputType */
4044 const struct attribute_desc output_type_desc
[] =
4046 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4047 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
4048 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4049 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4050 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540, .required
= TRUE
),
4054 const struct attribute_desc expect_input_type_desc
[] =
4056 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4057 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4058 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4059 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4060 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4061 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4062 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4063 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4064 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4067 const struct attribute_desc expect_output_type_desc
[] =
4069 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4070 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4071 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4072 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4073 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540),
4074 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4077 static const MFT_OUTPUT_STREAM_INFO empty_output_info
=
4079 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4081 static const MFT_INPUT_STREAM_INFO empty_input_info
=
4083 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4085 static const MFT_OUTPUT_STREAM_INFO expect_output_info
=
4087 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4091 static const MFT_INPUT_STREAM_INFO expect_input_info
=
4093 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4098 const struct buffer_desc output_buffer_desc
[] =
4100 {.length
= -1 /* variable */},
4102 const struct attribute_desc output_sample_attributes_key
[] =
4104 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4107 const struct attribute_desc output_sample_attributes
[] =
4109 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0),
4112 const struct sample_desc output_sample_desc
[] =
4115 .attributes
= output_sample_attributes_key
,
4116 .sample_time
= 0, .sample_duration
= 333333,
4117 .buffer_count
= 1, .buffers
= output_buffer_desc
,
4120 .attributes
= output_sample_attributes
,
4121 .sample_time
= 333333, .sample_duration
= 333333,
4122 .buffer_count
= 1, .buffers
= output_buffer_desc
, .repeat_count
= 4
4126 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
4127 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4128 IMFSample
*input_sample
, *output_sample
;
4129 DWORD status
, length
, output_status
;
4130 MFT_OUTPUT_DATA_BUFFER output
;
4131 IMFCollection
*output_samples
;
4132 const BYTE
*nv12frame_data
;
4133 IMFMediaType
*media_type
;
4134 ULONG nv12frame_data_len
;
4135 IMFTransform
*transform
;
4140 hr
= CoInitialize(NULL
);
4141 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4143 winetest_push_context("wmvenc");
4145 if (!check_mft_enum(MFT_CATEGORY_VIDEO_ENCODER
, &input_type
, &output_type
, class_id
))
4147 check_mft_get_info(class_id
, &expect_mft_info
);
4148 check_dmo_get_info(class_id
, &expect_dmo_info
);
4150 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4151 &IID_IMFTransform
, (void **)&transform
)))
4154 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4155 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4156 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4157 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4159 check_mft_optional_methods(transform
, 2);
4160 check_mft_get_attributes(transform
, NULL
, FALSE
);
4161 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_input_info
);
4162 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
4165 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4167 winetest_push_context("in 0 %lu", i
);
4168 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4169 ret
= IMFMediaType_Release(media_type
);
4170 ok(ret
<= 1, "Release returned %lu\n", ret
);
4171 winetest_pop_context();
4173 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4174 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
4177 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4179 winetest_push_context("out %lu", i
);
4180 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4181 ret
= IMFMediaType_Release(media_type
);
4182 ok(ret
<= 1, "Release returned %lu\n", ret
);
4183 winetest_pop_context();
4185 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4186 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
4188 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4189 check_mft_get_output_current_type(transform
, NULL
);
4191 check_mft_set_input_type_required(transform
, input_type_desc
);
4192 check_mft_set_input_type(transform
, input_type_desc
);
4193 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4195 check_mft_set_output_type_required(transform
, output_type_desc
);
4196 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4197 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4199 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
4200 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
4202 if (!has_video_processor
)
4204 win_skip("Skipping WMV encoder tests on Win7\n");
4208 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
4209 /* skip BMP header and RGB data from the dump */
4210 length
= *(DWORD
*)(nv12frame_data
+ 2);
4211 nv12frame_data_len
= nv12frame_data_len
- length
;
4212 nv12frame_data
= nv12frame_data
+ length
;
4213 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
4215 hr
= MFCreateCollection(&output_samples
);
4216 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4218 for (i
= 0; i
< 5; i
++)
4220 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
4221 hr
= IMFSample_SetSampleTime(input_sample
, i
* 333333);
4222 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4223 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
4224 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4225 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4226 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4227 ref
= IMFSample_Release(input_sample
);
4228 ok(ref
<= 1, "Release returned %ld\n", ref
);
4230 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4231 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4232 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4233 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4234 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4235 ref
= IMFSample_Release(output_sample
);
4236 ok(ref
== 1, "Release returned %ld\n", ref
);
4239 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmvencdata.bin");
4240 ok(ret
== 0, "got %lu%% diff\n", ret
);
4241 IMFCollection_Release(output_samples
);
4243 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4244 status
= 0xdeadbeef;
4245 memset(&output
, 0, sizeof(output
));
4246 output
.pSample
= output_sample
;
4247 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
4248 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4249 ok(output
.pSample
== output_sample
, "got pSample %p\n", output
.pSample
);
4250 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
4251 ok(status
== 0, "got status %#lx\n", status
);
4252 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
4253 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4254 ok(length
== 0, "got length %lu\n", length
);
4255 ret
= IMFSample_Release(output_sample
);
4256 ok(ret
== 0, "Release returned %lu\n", ret
);
4259 ret
= IMFTransform_Release(transform
);
4260 ok(ret
== 0, "Release returned %lu\n", ret
);
4263 winetest_pop_context();
4267 static void test_wmv_decoder(void)
4269 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
4270 const struct transform_info expect_mft_info
=
4272 .name
= L
"WMVideo Decoder MFT",
4273 .major_type
= &MFMediaType_Video
,
4276 {.subtype
= &MFVideoFormat_WMV1
},
4277 {.subtype
= &MFVideoFormat_WMV2
},
4278 {.subtype
= &MFVideoFormat_WMV3
},
4279 {.subtype
= &MEDIASUBTYPE_WMVP
},
4280 {.subtype
= &MEDIASUBTYPE_WVP2
},
4281 {.subtype
= &MEDIASUBTYPE_WMVR
},
4282 {.subtype
= &MEDIASUBTYPE_WMVA
},
4283 {.subtype
= &MFVideoFormat_WVC1
},
4284 {.subtype
= &MFVideoFormat_VC1S
},
4288 {.subtype
= &MFVideoFormat_YV12
},
4289 {.subtype
= &MFVideoFormat_YUY2
},
4290 {.subtype
= &MFVideoFormat_UYVY
},
4291 {.subtype
= &MFVideoFormat_YVYU
},
4292 {.subtype
= &MFVideoFormat_NV11
},
4293 {.subtype
= &MFVideoFormat_NV12
},
4294 {.subtype
= &DMOVideoFormat_RGB32
},
4295 {.subtype
= &DMOVideoFormat_RGB24
},
4296 {.subtype
= &DMOVideoFormat_RGB565
},
4297 {.subtype
= &DMOVideoFormat_RGB555
},
4298 {.subtype
= &DMOVideoFormat_RGB8
},
4301 const struct transform_info expect_dmo_info
=
4303 .name
= L
"WMVideo Decoder DMO",
4304 .major_type
= &MEDIATYPE_Video
,
4307 {.subtype
= &MEDIASUBTYPE_WMV1
},
4308 {.subtype
= &MEDIASUBTYPE_WMV2
},
4309 {.subtype
= &MEDIASUBTYPE_WMV3
},
4310 {.subtype
= &MEDIASUBTYPE_WMVA
},
4311 {.subtype
= &MEDIASUBTYPE_WVC1
},
4312 {.subtype
= &MEDIASUBTYPE_WMVP
},
4313 {.subtype
= &MEDIASUBTYPE_WVP2
},
4314 {.subtype
= &MFVideoFormat_VC1S
},
4318 {.subtype
= &MEDIASUBTYPE_YV12
},
4319 {.subtype
= &MEDIASUBTYPE_YUY2
},
4320 {.subtype
= &MEDIASUBTYPE_UYVY
},
4321 {.subtype
= &MEDIASUBTYPE_YVYU
},
4322 {.subtype
= &MEDIASUBTYPE_NV11
},
4323 {.subtype
= &MEDIASUBTYPE_NV12
},
4324 {.subtype
= &MEDIASUBTYPE_RGB32
},
4325 {.subtype
= &MEDIASUBTYPE_RGB24
},
4326 {.subtype
= &MEDIASUBTYPE_RGB565
},
4327 {.subtype
= &MEDIASUBTYPE_RGB555
},
4328 {.subtype
= &MEDIASUBTYPE_RGB8
},
4332 static const struct attribute_desc expect_common_attributes
[] =
4334 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4337 static const media_type_desc expect_available_inputs
[] =
4339 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
)},
4340 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
)},
4341 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVA
)},
4342 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVP
)},
4343 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WVP2
)},
4344 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV_Unknown
)},
4345 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WVC1
)},
4346 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV3
)},
4347 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_VC1S
)},
4349 static const MFVideoArea actual_aperture
= {.Area
={96,96}};
4350 static const DWORD actual_width
= 96, actual_height
= 96;
4351 const struct attribute_desc expect_output_attributes
[] =
4353 ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
4354 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
4355 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4356 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4357 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4358 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 2),
4361 const media_type_desc expect_available_outputs
[] =
4364 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4365 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4366 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4367 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4368 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4371 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4372 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
4373 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4374 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4375 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4378 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4379 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
4380 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4381 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4382 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4385 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4386 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
4387 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4388 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4389 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4392 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4393 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
4394 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4395 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4396 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4399 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4400 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
4401 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4402 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4403 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4406 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4407 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
4408 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4409 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4410 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4413 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4414 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
4415 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4416 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4417 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4420 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4421 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
4422 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4423 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
4424 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
4427 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4428 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
4429 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4430 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 3),
4431 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3),
4434 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4435 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
4436 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4437 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4438 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4439 /* ATTR_BLOB(MF_MT_PALETTE, ... with 12 elements), */
4442 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4443 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
4444 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4445 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4446 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4449 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4450 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB8
),
4451 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4452 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4453 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
),
4454 /* ATTR_BLOB(MF_MT_PALETTE, ... with 904 elements), */
4457 const struct attribute_desc expect_attributes
[] =
4459 ATTR_UINT32(MF_LOW_LATENCY
, 0),
4460 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1),
4461 ATTR_UINT32(MF_SA_D3D_AWARE
, 1),
4462 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0),
4463 /* more attributes from CODECAPI */
4466 const struct attribute_desc input_type_desc
[] =
4468 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4469 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
4470 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4473 const struct attribute_desc output_type_desc
[] =
4475 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4476 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4477 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4480 const struct attribute_desc expect_input_type_desc
[] =
4482 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4483 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4484 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4485 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4488 const struct attribute_desc expect_output_type_desc
[] =
4490 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4491 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4492 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4493 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4494 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4495 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4496 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
4497 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4498 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4501 const MFT_OUTPUT_STREAM_INFO expect_output_info
=
4503 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
4507 const MFT_OUTPUT_STREAM_INFO empty_output_info
=
4509 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
4511 const MFT_INPUT_STREAM_INFO expect_input_info
=
4517 const struct attribute_desc output_sample_attributes
[] =
4519 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4522 const struct buffer_desc output_buffer_desc_nv12
=
4524 .length
= actual_width
* actual_height
* 3 / 2,
4525 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
4527 const struct sample_desc output_sample_desc_nv12
=
4529 .attributes
= output_sample_attributes
,
4530 .sample_time
= 0, .sample_duration
= 333333,
4531 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
4534 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4535 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
4536 IMFSample
*input_sample
, *output_sample
;
4537 IMFCollection
*output_samples
;
4538 IMFMediaType
*media_type
;
4539 IMFTransform
*transform
;
4540 const BYTE
*wmvenc_data
;
4541 ULONG wmvenc_data_len
;
4542 DWORD output_status
;
4546 hr
= CoInitialize(NULL
);
4547 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4549 winetest_push_context("wmvdec");
4551 if (!has_video_processor
)
4553 win_skip("Skipping inconsistent WMV decoder tests on Win7\n");
4557 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
4559 check_mft_get_info(class_id
, &expect_mft_info
);
4560 check_dmo_get_info(class_id
, &expect_dmo_info
);
4562 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4563 &IID_IMFTransform
, (void **)&transform
)))
4566 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4567 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4568 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4569 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4571 check_mft_optional_methods(transform
, 1);
4572 check_mft_get_attributes(transform
, expect_attributes
, TRUE
);
4574 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4576 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
4578 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4580 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
4583 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4585 winetest_push_context("in %lu", i
);
4586 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4587 check_media_type(media_type
, expect_common_attributes
, -1);
4588 check_media_type(media_type
, expect_available_inputs
[i
], -1);
4589 ret
= IMFMediaType_Release(media_type
);
4590 ok(!ret
, "Release returned %lu\n", ret
);
4591 winetest_pop_context();
4594 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4596 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
4598 if (hr
== E_NOTIMPL
)
4601 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4602 check_mft_get_output_current_type(transform
, NULL
);
4604 check_mft_set_input_type_required(transform
, input_type_desc
);
4605 check_mft_set_input_type(transform
, input_type_desc
);
4606 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4609 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4611 winetest_push_context("out %lu", i
);
4612 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4613 check_media_type(media_type
, expect_common_attributes
, -1);
4614 check_media_type(media_type
, expect_output_attributes
, -1);
4615 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4616 ret
= IMFMediaType_Release(media_type
);
4617 ok(!ret
, "Release returned %lu\n", ret
);
4618 winetest_pop_context();
4620 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4621 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
4623 check_mft_set_output_type_required(transform
, output_type_desc
);
4624 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4625 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4627 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
4628 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
4630 load_resource(L
"wmvencdata.bin", &wmvenc_data
, &wmvenc_data_len
);
4632 input_sample
= create_sample(wmvenc_data
+ sizeof(DWORD
), *(DWORD
*)wmvenc_data
);
4633 wmvenc_data_len
-= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
4634 wmvenc_data
+= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
4635 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4636 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4637 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
4638 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4639 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4640 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4641 ret
= IMFSample_Release(input_sample
);
4642 ok(ret
<= 1, "Release returned %ld\n", ret
);
4644 hr
= MFCreateCollection(&output_samples
);
4645 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4647 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4648 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
4650 winetest_push_context("%lu", i
);
4651 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4652 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4653 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4654 ref
= IMFSample_Release(output_sample
);
4655 ok(ref
== 1, "Release returned %ld\n", ref
);
4656 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4657 winetest_pop_context();
4659 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4660 ret
= IMFSample_Release(output_sample
);
4661 ok(ret
== 0, "Release returned %lu\n", ret
);
4662 ok(i
== 1, "got %lu output samples\n", i
);
4664 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
4665 ok(ret
== 0, "got %lu%% diff\n", ret
);
4666 IMFCollection_Release(output_samples
);
4669 ret
= IMFTransform_Release(transform
);
4670 ok(ret
== 0, "Release returned %lu\n", ret
);
4673 winetest_pop_context();
4677 static void test_wmv_decoder_media_object(void)
4679 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
4680 const DMO_MEDIA_TYPE expected_input_types
[] =
4682 {MFMediaType_Video
, MEDIASUBTYPE_WMV1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4683 {MFMediaType_Video
, MEDIASUBTYPE_WMV2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4684 {MFMediaType_Video
, MEDIASUBTYPE_WMVA
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4685 {MFMediaType_Video
, MEDIASUBTYPE_WMVP
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4686 {MFMediaType_Video
, MEDIASUBTYPE_WVP2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4687 {MFMediaType_Video
, MFVideoFormat_WMV_Unknown
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4688 {MFMediaType_Video
, MEDIASUBTYPE_WVC1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4689 {MFMediaType_Video
, MEDIASUBTYPE_WMV3
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4690 {MFMediaType_Video
, MFVideoFormat_VC1S
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4692 const VIDEOINFOHEADER expected_output_info
[] =
4694 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('N', 'V', '1', '2'), 384, 0, 0, 0, 0}},
4695 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('Y', 'V', '1', '2'), 384, 0, 0, 0, 0}},
4696 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('I', 'Y', 'U', 'V'), 384, 0, 0, 0, 0}},
4697 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('I', '4', '2', '0'), 384, 0, 0, 0, 0}},
4698 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('Y', 'U', 'Y', '2'), 512, 0, 0, 0, 0}},
4699 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('U', 'Y', 'V', 'Y'), 512, 0, 0, 0, 0}},
4700 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, MAKEFOURCC('Y', 'V', 'Y', 'U'), 512, 0, 0, 0, 0}},
4701 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 12, MAKEFOURCC('N', 'V', '1', '1'), 384, 0, 0, 0, 0}},
4702 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 32, BI_RGB
, 1024, 0, 0, 0, 0}},
4703 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 24, BI_RGB
, 768, 0, 0, 0, 0}},
4704 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_BITFIELDS
, 512, 0, 0, 0, 0}},
4705 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_RGB
, 512, 0, 0, 0, 0}},
4706 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 8, BI_RGB
, 256, 0, 0, 226, 226}},
4708 const DMO_MEDIA_TYPE expected_output_types
[] =
4710 {MFMediaType_Video
, MEDIASUBTYPE_NV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[0]},
4711 {MFMediaType_Video
, MEDIASUBTYPE_YV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[1]},
4712 {MFMediaType_Video
, MEDIASUBTYPE_IYUV
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[2]},
4713 {MFMediaType_Video
, MEDIASUBTYPE_I420
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[3]},
4714 {MFMediaType_Video
, MEDIASUBTYPE_YUY2
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[4]},
4715 {MFMediaType_Video
, MEDIASUBTYPE_UYVY
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[5]},
4716 {MFMediaType_Video
, MEDIASUBTYPE_YVYU
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[6]},
4717 {MFMediaType_Video
, MEDIASUBTYPE_NV11
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[7]},
4718 {MFMediaType_Video
, MEDIASUBTYPE_RGB32
, TRUE
, FALSE
, 1024, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[8]},
4719 {MFMediaType_Video
, MEDIASUBTYPE_RGB24
, TRUE
, FALSE
, 768, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[9]},
4720 {MFMediaType_Video
, MEDIASUBTYPE_RGB565
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 100, (BYTE
*)&expected_output_info
[10]},
4721 {MFMediaType_Video
, MEDIASUBTYPE_RGB555
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[11]},
4722 {MFMediaType_Video
, MEDIASUBTYPE_RGB8
, TRUE
, FALSE
, 256, FORMAT_VideoInfo
, NULL
, 1112, (BYTE
*)&expected_output_info
[12]},
4724 const struct set_type_arg
4729 MEDIA_TYPE_NULL
= 0,
4730 MEDIA_TYPE_GOOD
= 1,
4736 set_type_arg_tests
[] =
4738 {1, MEDIA_TYPE_NULL
, 0, DMO_E_INVALIDSTREAMINDEX
},
4739 {1, MEDIA_TYPE_NULL
, 0x4, DMO_E_INVALIDSTREAMINDEX
},
4740 {1, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_CLEAR
, DMO_E_INVALIDSTREAMINDEX
},
4741 {1, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_TEST_ONLY
, DMO_E_INVALIDSTREAMINDEX
},
4742 {1, MEDIA_TYPE_GOOD
, 0, DMO_E_INVALIDSTREAMINDEX
},
4743 {1, MEDIA_TYPE_GOOD
, 0x4, DMO_E_INVALIDSTREAMINDEX
},
4744 {1, MEDIA_TYPE_GOOD
, DMO_SET_TYPEF_CLEAR
, DMO_E_INVALIDSTREAMINDEX
},
4745 {1, MEDIA_TYPE_GOOD
, DMO_SET_TYPEF_TEST_ONLY
, DMO_E_INVALIDSTREAMINDEX
},
4746 {1, MEDIA_TYPE_BAD
, 0, DMO_E_INVALIDSTREAMINDEX
},
4747 {1, MEDIA_TYPE_BAD
, 0x4, DMO_E_INVALIDSTREAMINDEX
},
4748 {1, MEDIA_TYPE_BAD
, DMO_SET_TYPEF_CLEAR
, DMO_E_INVALIDSTREAMINDEX
},
4749 {1, MEDIA_TYPE_BAD
, DMO_SET_TYPEF_TEST_ONLY
, DMO_E_INVALIDSTREAMINDEX
},
4750 {0, MEDIA_TYPE_BAD
, 0, DMO_E_TYPE_NOT_ACCEPTED
},
4751 {0, MEDIA_TYPE_BAD
, 0x4, DMO_E_TYPE_NOT_ACCEPTED
},
4752 {0, MEDIA_TYPE_BAD
, DMO_SET_TYPEF_CLEAR
, DMO_E_TYPE_NOT_ACCEPTED
},
4753 {0, MEDIA_TYPE_BAD
, DMO_SET_TYPEF_TEST_ONLY
, DMO_E_TYPE_NOT_ACCEPTED
},
4754 {0, MEDIA_TYPE_NULL
, 0, DMO_E_TYPE_NOT_ACCEPTED
},
4755 {0, MEDIA_TYPE_NULL
, 0x4, DMO_E_TYPE_NOT_ACCEPTED
},
4756 {0, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_TEST_ONLY
, DMO_E_TYPE_NOT_ACCEPTED
},
4757 {0, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_CLEAR
, S_OK
},
4758 {0, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_CLEAR
| 0x4, S_OK
},
4759 {0, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_CLEAR
| DMO_SET_TYPEF_TEST_ONLY
, S_OK
},
4760 {0, MEDIA_TYPE_NULL
, DMO_SET_TYPEF_CLEAR
| DMO_SET_TYPEF_TEST_ONLY
| 0x4, S_OK
},
4761 {0, MEDIA_TYPE_GOOD
, 0x4, S_OK
},
4762 {0, MEDIA_TYPE_GOOD
, DMO_SET_TYPEF_CLEAR
, S_OK
},
4763 {0, MEDIA_TYPE_GOOD
, DMO_SET_TYPEF_CLEAR
| DMO_SET_TYPEF_TEST_ONLY
, S_OK
},
4765 DMO_MEDIA_TYPE media_type
, *input_type
;
4766 IMediaObject
*media_object
;
4767 DWORD in_count
, out_count
;
4768 VIDEOINFOHEADER
*header
;
4773 winetest_push_context("wmvdec");
4775 if (!has_video_processor
)
4777 win_skip("Skipping inconsistent WMV decoder media object tests on Win7.\n");
4778 winetest_pop_context();
4782 hr
= CoInitialize(NULL
);
4783 ok(hr
== S_OK
, "CoInitialize failed, hr %#lx.\n", hr
);
4785 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMediaObject
, (void **)&media_object
);
4786 ok(hr
== S_OK
, "CoCreateInstance returned %#lx.\n", hr
);
4788 /* Test GetStreamCount. */
4789 in_count
= out_count
= 0xdeadbeef;
4790 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, &out_count
);
4791 ok(hr
== S_OK
, "GetStreamCount returned %#lx.\n", hr
);
4792 ok(in_count
== 1, "Got unexpected in_count %lu.\n", in_count
);
4793 ok(out_count
== 1, "Got unexpected in_count %lu.\n", out_count
);
4795 /* Test GetStreamCount with invalid arguments. */
4796 in_count
= out_count
= 0xdeadbeef;
4797 hr
= IMediaObject_GetStreamCount(media_object
, NULL
, &out_count
);
4798 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
4799 ok(out_count
== 0xdeadbeef, "Got unexpected out_count %lu.\n", out_count
);
4800 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, NULL
);
4801 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
4802 ok(in_count
== 0xdeadbeef, "Got unexpected in_count %lu.\n", in_count
);
4804 /* Test GetInputType. */
4805 check_dmo_get_input_type(media_object
, expected_input_types
, ARRAY_SIZE(expected_input_types
));
4807 /* Test SetInputType. */
4808 input_type
= (DMO_MEDIA_TYPE
*)buffer
;
4809 header
= (VIDEOINFOHEADER
*)(input_type
+ 1);
4810 for (i
= 0; i
< ARRAY_SIZE(expected_input_types
); ++i
)
4812 const GUID
*subtype
= &expected_input_types
[i
].subtype
;
4814 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
4815 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
4816 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
4817 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
4818 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
4820 skip("Skipping SetInputType tests for video subtype %s.\n", debugstr_guid(subtype
));
4824 winetest_push_context("in %lu", i
);
4826 /* Test setting the type. */
4827 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4828 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4829 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4830 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, 0);
4831 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4832 header
->dwBitRate
= 0xdeadbeef;
4833 header
->dwBitErrorRate
= 0xdeadbeef;
4834 header
->AvgTimePerFrame
= 0xdeadbeef;
4835 header
->bmiHeader
.biPlanes
= 0xdead;
4836 header
->bmiHeader
.biBitCount
= 0xdead;
4837 header
->bmiHeader
.biSizeImage
= 0xdeadbeef;
4838 header
->bmiHeader
.biXPelsPerMeter
= 0xdead;
4839 header
->bmiHeader
.biYPelsPerMeter
= 0xdead;
4840 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, 0);
4841 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4843 /* Test invalid major type. */
4844 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4845 input_type
->majortype
= MFMediaType_Default
;
4846 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4847 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4849 /* Test invalid subtype. */
4850 init_dmo_media_type_video(input_type
, &MEDIASUBTYPE_None
, 96, 96);
4851 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4852 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4854 /* Test invalid format type. */
4855 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4856 input_type
->formattype
= FORMAT_None
;
4857 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4858 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4860 /* Test invalid format size. */
4861 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4862 input_type
->cbFormat
= 1;
4863 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4864 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4866 /* Test NULL format pointer. */
4867 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4868 input_type
->pbFormat
= NULL
;
4869 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4870 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4872 /* Test video header struct size. */
4873 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4874 header
->bmiHeader
.biSize
= 0;
4875 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4877 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4878 header
->bmiHeader
.biSize
= 1;
4879 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4881 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4882 header
->bmiHeader
.biSize
= 0xdeadbeef;
4883 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4885 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4888 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4889 header
->bmiHeader
.biWidth
= 0;
4890 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4892 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4893 header
->bmiHeader
.biWidth
= -1;
4894 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4896 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4897 header
->bmiHeader
.biWidth
= 4096 + 1;
4898 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4900 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4901 header
->bmiHeader
.biWidth
= 4096;
4902 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4903 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4906 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4907 header
->bmiHeader
.biHeight
= 0;
4908 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4910 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4911 header
->bmiHeader
.biHeight
= 4096 + 1;
4912 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4914 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4915 header
->bmiHeader
.biHeight
= 4096;
4916 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4917 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4918 header
->bmiHeader
.biHeight
= -4096;
4919 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4920 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4922 /* Test compression. */
4923 init_dmo_media_type_video(input_type
, subtype
, 96, 96);
4924 header
->bmiHeader
.biCompression
= 0;
4925 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4927 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4928 header
->bmiHeader
.biCompression
= 1;
4929 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4930 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4931 header
->bmiHeader
.biCompression
= 2;
4932 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4933 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4934 header
->bmiHeader
.biCompression
= 0xdeadbeef;
4935 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, DMO_SET_TYPEF_TEST_ONLY
);
4936 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4938 winetest_pop_context();
4941 /* Test SetInputType arguments. */
4942 memset(&media_type
, 0, sizeof(media_type
));
4943 init_dmo_media_type_video(input_type
, &expected_input_types
[0].subtype
, 96, 96);
4944 for (i
= 0; i
< ARRAY_SIZE(set_type_arg_tests
); ++i
)
4946 const struct set_type_arg
*test
= &set_type_arg_tests
[i
];
4947 DMO_MEDIA_TYPE
*type
;
4949 winetest_push_context("Test %lu", i
);
4951 if (test
->media_type
== MEDIA_TYPE_GOOD
)
4953 else if (test
->media_type
== MEDIA_TYPE_BAD
)
4958 hr
= IMediaObject_SetInputType(media_object
, test
->stream_index
, type
, test
->flags
);
4959 ok(hr
== test
->hr
, "SetInputType returned unexpected hr %#lx, expected %#lx.\n", hr
, test
->hr
);
4961 winetest_pop_context();
4964 /* Test GetOutputType without setting input type. */
4965 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
4966 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4967 hr
= IMediaObject_GetOutputType(media_object
, 0, 0, &media_type
);
4969 ok(hr
== DMO_E_TYPE_NOT_SET
, "GetOutputType returned unexpected hr %#lx.\n", hr
);
4971 /* Test GetOutputType after setting input type. */
4972 for (i
= 0; i
< ARRAY_SIZE(expected_input_types
); ++i
)
4974 const GUID
*subtype
= &expected_input_types
[i
].subtype
;
4975 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
4976 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
4977 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
4978 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
4979 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
4981 skip("Skipping GetOutputType tests for input subtype %s.\n", debugstr_guid(subtype
));
4985 winetest_push_context("in %lu", i
);
4987 init_dmo_media_type_video(input_type
, &expected_input_types
[i
].subtype
, 16, 16);
4988 hr
= IMediaObject_SetInputType(media_object
, 0, input_type
, 0);
4989 ok(hr
== S_OK
, "SetInputType returned unexpected hr %#lx.\n", hr
);
4992 check_dmo_get_output_type(media_object
, expected_output_types
, ARRAY_SIZE(expected_output_types
));
4994 winetest_pop_context();
4997 ret
= IMediaObject_Release(media_object
);
4998 ok(ret
== 0, "Release returned %lu\n", ret
);
5000 winetest_pop_context();
5003 static void test_color_convert(void)
5005 const GUID
*const class_id
= &CLSID_CColorConvertDMO
;
5006 const struct transform_info expect_mft_info
=
5008 .name
= L
"Color Converter MFT",
5009 .major_type
= &MFMediaType_Video
,
5012 {.subtype
= &MFVideoFormat_YV12
},
5013 {.subtype
= &MFVideoFormat_YUY2
},
5014 {.subtype
= &MFVideoFormat_UYVY
},
5015 {.subtype
= &MFVideoFormat_AYUV
},
5016 {.subtype
= &MFVideoFormat_NV12
},
5017 {.subtype
= &DMOVideoFormat_RGB32
},
5018 {.subtype
= &DMOVideoFormat_RGB565
},
5019 {.subtype
= &MFVideoFormat_I420
},
5020 {.subtype
= &MFVideoFormat_IYUV
},
5021 {.subtype
= &MFVideoFormat_YVYU
},
5022 {.subtype
= &DMOVideoFormat_RGB24
},
5023 {.subtype
= &DMOVideoFormat_RGB555
},
5024 {.subtype
= &DMOVideoFormat_RGB8
},
5025 {.subtype
= &MEDIASUBTYPE_V216
},
5026 {.subtype
= &MEDIASUBTYPE_V410
},
5027 {.subtype
= &MFVideoFormat_NV11
},
5028 {.subtype
= &MFVideoFormat_Y41P
},
5029 {.subtype
= &MFVideoFormat_Y41T
},
5030 {.subtype
= &MFVideoFormat_Y42T
},
5031 {.subtype
= &MFVideoFormat_YVU9
},
5035 {.subtype
= &MFVideoFormat_YV12
},
5036 {.subtype
= &MFVideoFormat_YUY2
},
5037 {.subtype
= &MFVideoFormat_UYVY
},
5038 {.subtype
= &MFVideoFormat_AYUV
},
5039 {.subtype
= &MFVideoFormat_NV12
},
5040 {.subtype
= &DMOVideoFormat_RGB32
},
5041 {.subtype
= &DMOVideoFormat_RGB565
},
5042 {.subtype
= &MFVideoFormat_I420
},
5043 {.subtype
= &MFVideoFormat_IYUV
},
5044 {.subtype
= &MFVideoFormat_YVYU
},
5045 {.subtype
= &DMOVideoFormat_RGB24
},
5046 {.subtype
= &DMOVideoFormat_RGB555
},
5047 {.subtype
= &DMOVideoFormat_RGB8
},
5048 {.subtype
= &MEDIASUBTYPE_V216
},
5049 {.subtype
= &MEDIASUBTYPE_V410
},
5050 {.subtype
= &MFVideoFormat_NV11
},
5053 const struct transform_info expect_dmo_info
=
5055 .name
= L
"Color Converter DMO",
5056 .major_type
= &MEDIATYPE_Video
,
5059 {.subtype
= &MEDIASUBTYPE_YV12
},
5060 {.subtype
= &MEDIASUBTYPE_YUY2
},
5061 {.subtype
= &MEDIASUBTYPE_UYVY
},
5062 {.subtype
= &MEDIASUBTYPE_AYUV
},
5063 {.subtype
= &MEDIASUBTYPE_NV12
},
5064 {.subtype
= &MEDIASUBTYPE_RGB32
},
5065 {.subtype
= &MEDIASUBTYPE_RGB565
},
5066 {.subtype
= &MEDIASUBTYPE_I420
},
5067 {.subtype
= &MEDIASUBTYPE_IYUV
},
5068 {.subtype
= &MEDIASUBTYPE_YVYU
},
5069 {.subtype
= &MEDIASUBTYPE_RGB24
},
5070 {.subtype
= &MEDIASUBTYPE_RGB555
},
5071 {.subtype
= &MEDIASUBTYPE_RGB8
},
5072 {.subtype
= &MEDIASUBTYPE_V216
},
5073 {.subtype
= &MEDIASUBTYPE_V410
},
5074 {.subtype
= &MEDIASUBTYPE_NV11
},
5075 {.subtype
= &MEDIASUBTYPE_Y41P
},
5076 {.subtype
= &MEDIASUBTYPE_Y41T
},
5077 {.subtype
= &MEDIASUBTYPE_Y42T
},
5078 {.subtype
= &MEDIASUBTYPE_YVU9
},
5082 {.subtype
= &MEDIASUBTYPE_YV12
},
5083 {.subtype
= &MEDIASUBTYPE_YUY2
},
5084 {.subtype
= &MEDIASUBTYPE_UYVY
},
5085 {.subtype
= &MEDIASUBTYPE_AYUV
},
5086 {.subtype
= &MEDIASUBTYPE_NV12
},
5087 {.subtype
= &MEDIASUBTYPE_RGB32
},
5088 {.subtype
= &MEDIASUBTYPE_RGB565
},
5089 {.subtype
= &MEDIASUBTYPE_I420
},
5090 {.subtype
= &MEDIASUBTYPE_IYUV
},
5091 {.subtype
= &MEDIASUBTYPE_YVYU
},
5092 {.subtype
= &MEDIASUBTYPE_RGB24
},
5093 {.subtype
= &MEDIASUBTYPE_RGB555
},
5094 {.subtype
= &MEDIASUBTYPE_RGB8
},
5095 {.subtype
= &MEDIASUBTYPE_V216
},
5096 {.subtype
= &MEDIASUBTYPE_V410
},
5097 {.subtype
= &MEDIASUBTYPE_NV11
},
5101 static const media_type_desc expect_available_inputs
[20] =
5103 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5104 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5105 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
5106 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
5107 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
5108 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
5109 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
5110 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
5111 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
5112 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
5113 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
5114 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
5115 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
5116 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
5117 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
5118 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
5119 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
5120 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
5121 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
5122 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
5124 static const media_type_desc expect_available_outputs
[16] =
5126 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5127 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5128 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
5129 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
5130 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
5131 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
5132 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
5133 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
5134 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
5135 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
5136 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
5137 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
5138 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
5139 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
5140 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
5141 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
5143 static const media_type_desc expect_available_common
=
5145 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5146 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5147 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5150 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
5151 static const DWORD actual_width
= 96, actual_height
= 96;
5152 const struct attribute_desc input_type_desc
[] =
5154 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5155 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5156 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5157 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5160 const struct attribute_desc output_type_desc
[] =
5162 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5163 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5164 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5167 const struct attribute_desc expect_input_type_desc
[] =
5169 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5170 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
5171 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5172 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5173 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5174 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5175 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5176 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5177 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5180 const struct attribute_desc expect_output_type_desc
[] =
5182 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5183 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
5184 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5185 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
5186 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
5187 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5188 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5189 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5192 const MFT_OUTPUT_STREAM_INFO output_info
=
5194 .cbSize
= actual_width
* actual_height
* 4,
5197 const MFT_INPUT_STREAM_INFO input_info
=
5199 .cbSize
= actual_width
* actual_height
* 3 / 2,
5203 const struct buffer_desc output_buffer_desc
=
5205 .length
= actual_width
* actual_height
* 4,
5206 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.right
= 82, .bottom
= 84},
5208 const struct attribute_desc output_sample_attributes
[] =
5210 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0, .todo
= TRUE
),
5213 const struct sample_desc output_sample_desc
=
5215 .attributes
= output_sample_attributes
,
5216 .sample_time
= 0, .sample_duration
= 10000000,
5217 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
5220 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
5221 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
5222 IMFSample
*input_sample
, *output_sample
;
5223 IMFCollection
*output_samples
;
5224 DWORD length
, output_status
;
5225 const BYTE
*nv12frame_data
;
5226 ULONG nv12frame_data_len
;
5227 IMFMediaType
*media_type
;
5228 IMFTransform
*transform
;
5232 hr
= CoInitialize(NULL
);
5233 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5235 winetest_push_context("colorconv");
5237 if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, class_id
))
5239 check_mft_get_info(class_id
, &expect_mft_info
);
5240 check_dmo_get_info(class_id
, &expect_dmo_info
);
5242 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5243 &IID_IMFTransform
, (void **)&transform
)))
5246 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5247 check_interface(transform
, &IID_IMediaObject
, TRUE
);
5248 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
5250 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
5252 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
5253 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
5255 check_mft_optional_methods(transform
, 1);
5256 check_mft_get_attributes(transform
, NULL
, FALSE
);
5257 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5258 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5261 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
5263 winetest_push_context("out %lu", i
);
5264 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5265 check_media_type(media_type
, expect_available_common
, -1);
5266 check_media_type(media_type
, expect_available_outputs
[i
], -1);
5267 ret
= IMFMediaType_Release(media_type
);
5268 ok(ret
== 0, "Release returned %lu\n", ret
);
5269 winetest_pop_context();
5271 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5272 ok(i
== 16, "%lu output media types\n", i
);
5275 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5277 winetest_push_context("in %lu", i
);
5278 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5279 check_media_type(media_type
, expect_available_common
, -1);
5280 check_media_type(media_type
, expect_available_inputs
[i
], -1);
5281 ret
= IMFMediaType_Release(media_type
);
5282 ok(ret
== 0, "Release returned %lu\n", ret
);
5283 winetest_pop_context();
5285 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5286 ok(i
== 20, "%lu input media types\n", i
);
5288 check_mft_set_output_type_required(transform
, output_type_desc
);
5289 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
5290 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
5292 check_mft_set_input_type_required(transform
, input_type_desc
);
5293 check_mft_set_input_type(transform
, input_type_desc
);
5294 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
5296 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5297 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5299 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
5300 /* skip BMP header and RGB data from the dump */
5301 length
= *(DWORD
*)(nv12frame_data
+ 2);
5302 nv12frame_data_len
= nv12frame_data_len
- length
;
5303 nv12frame_data
= nv12frame_data
+ length
;
5304 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
5306 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
5307 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5308 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
5309 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
5310 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
5311 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5312 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5313 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5314 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5315 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
5316 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
5317 ret
= IMFSample_Release(input_sample
);
5318 ok(ret
<= 1, "Release returned %ld\n", ret
);
5320 hr
= MFCreateCollection(&output_samples
);
5321 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
5323 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5324 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5325 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5326 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5327 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5328 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5329 ref
= IMFSample_Release(output_sample
);
5330 ok(ref
== 1, "Release returned %ld\n", ref
);
5332 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame.bmp");
5333 ok(ret
<= 4 /* small and harmless diff in Wine vs Windows */, "got %lu%% diff\n", ret
);
5334 IMFCollection_Release(output_samples
);
5336 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5337 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5338 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5339 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5340 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
5341 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
5342 ok(length
== 0, "got length %lu\n", length
);
5343 ret
= IMFSample_Release(output_sample
);
5344 ok(ret
== 0, "Release returned %lu\n", ret
);
5346 ret
= IMFTransform_Release(transform
);
5347 ok(ret
== 0, "Release returned %ld\n", ret
);
5350 winetest_pop_context();
5354 static void test_video_processor(void)
5356 const GUID
*const class_id
= &CLSID_VideoProcessorMFT
;
5357 const struct transform_info expect_mft_info
=
5359 .name
= L
"Microsoft Video Processor MFT",
5360 .major_type
= &MFMediaType_Video
,
5363 {.subtype
= &MFVideoFormat_IYUV
},
5364 {.subtype
= &MFVideoFormat_YV12
},
5365 {.subtype
= &MFVideoFormat_NV12
},
5366 {.subtype
= &MFVideoFormat_YUY2
},
5367 {.subtype
= &MFVideoFormat_ARGB32
},
5368 {.subtype
= &MFVideoFormat_RGB32
},
5369 {.subtype
= &MFVideoFormat_NV11
},
5370 {.subtype
= &MFVideoFormat_AYUV
},
5371 {.subtype
= &MFVideoFormat_UYVY
},
5372 {.subtype
= &MEDIASUBTYPE_P208
},
5373 {.subtype
= &MFVideoFormat_RGB24
},
5374 {.subtype
= &MFVideoFormat_RGB555
},
5375 {.subtype
= &MFVideoFormat_RGB565
},
5376 {.subtype
= &MFVideoFormat_RGB8
},
5377 {.subtype
= &MFVideoFormat_I420
},
5378 {.subtype
= &MFVideoFormat_Y216
},
5379 {.subtype
= &MFVideoFormat_v410
},
5380 {.subtype
= &MFVideoFormat_Y41P
},
5381 {.subtype
= &MFVideoFormat_Y41T
},
5382 {.subtype
= &MFVideoFormat_Y42T
},
5383 {.subtype
= &MFVideoFormat_YVYU
},
5384 {.subtype
= &MFVideoFormat_420O
},
5388 {.subtype
= &MFVideoFormat_IYUV
},
5389 {.subtype
= &MFVideoFormat_YV12
},
5390 {.subtype
= &MFVideoFormat_NV12
},
5391 {.subtype
= &MFVideoFormat_YUY2
},
5392 {.subtype
= &MFVideoFormat_ARGB32
},
5393 {.subtype
= &MFVideoFormat_RGB32
},
5394 {.subtype
= &MFVideoFormat_NV11
},
5395 {.subtype
= &MFVideoFormat_AYUV
},
5396 {.subtype
= &MFVideoFormat_UYVY
},
5397 {.subtype
= &MEDIASUBTYPE_P208
},
5398 {.subtype
= &MFVideoFormat_RGB24
},
5399 {.subtype
= &MFVideoFormat_RGB555
},
5400 {.subtype
= &MFVideoFormat_RGB565
},
5401 {.subtype
= &MFVideoFormat_RGB8
},
5402 {.subtype
= &MFVideoFormat_I420
},
5403 {.subtype
= &MFVideoFormat_Y216
},
5404 {.subtype
= &MFVideoFormat_v410
},
5405 {.subtype
= &MFVideoFormat_Y41P
},
5406 {.subtype
= &MFVideoFormat_Y41T
},
5407 {.subtype
= &MFVideoFormat_Y42T
},
5408 {.subtype
= &MFVideoFormat_YVYU
},
5411 const GUID expect_available_inputs_w8
[] =
5422 MFVideoFormat_ARGB32
,
5423 MFVideoFormat_RGB32
,
5424 MFVideoFormat_RGB24
,
5427 MFVideoFormat_RGB555
,
5428 MFVideoFormat_RGB565
,
5436 const GUID expect_available_inputs_w10
[] =
5452 MFVideoFormat_ARGB32
,
5453 MFVideoFormat_ABGR32
,
5454 MFVideoFormat_RGB32
,
5455 MFVideoFormat_A2R10G10B10
,
5456 MFVideoFormat_A16B16G16R16F
,
5457 MFVideoFormat_RGB24
,
5460 MFVideoFormat_RGB555
,
5461 MFVideoFormat_RGB565
,
5469 const GUID expect_available_outputs
[] =
5471 MFVideoFormat_A2R10G10B10
, /* enumerated with MFVideoFormat_P010 input */
5472 MFVideoFormat_P010
, /* enumerated with MFVideoFormat_A2R10G10B10 input */
5477 MFVideoFormat_RGB24
,
5478 MFVideoFormat_ARGB32
,
5479 MFVideoFormat_RGB32
,
5481 MFVideoFormat_Y216
, /* enumerated with some input formats */
5482 MFVideoFormat_UYVY
, /* enumerated with some input formats */
5483 MFVideoFormat_YVYU
, /* enumerated with some input formats */
5485 MFVideoFormat_RGB555
,
5486 MFVideoFormat_RGB565
,
5487 MFVideoFormat_AYUV
, /* some inputs enumerate MFVideoFormat_AYUV after RGB565 */
5488 MFVideoFormat_NV12
, /* P010 enumerates NV12 after (A)RGB32 formats */
5489 MFVideoFormat_A16B16G16R16F
, /* enumerated with MFVideoFormat_P010 input */
5491 static const media_type_desc expect_available_common
=
5493 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5495 static const struct attribute_desc expect_transform_attributes
[] =
5497 ATTR_UINT32(MFT_SUPPORT_3DVIDEO
, 1, .todo
= TRUE
),
5498 /* ATTR_UINT32(MF_SA_D3D_AWARE, 1), only on W7 */
5502 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
5503 static const DWORD actual_width
= 96, actual_height
= 96;
5504 const struct attribute_desc input_type_desc
[] =
5506 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5507 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5508 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5509 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5512 const struct attribute_desc output_type_desc
[] =
5514 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5515 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5516 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5517 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5520 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0};
5521 const MFT_INPUT_STREAM_INFO initial_input_info
= {0};
5522 MFT_OUTPUT_STREAM_INFO output_info
= {0};
5523 MFT_INPUT_STREAM_INFO input_info
= {0};
5525 const struct buffer_desc output_buffer_desc
=
5527 .length
= actual_width
* actual_height
* 4,
5528 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
5530 const struct attribute_desc output_sample_attributes
[] =
5532 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1, .todo
= TRUE
),
5535 const struct sample_desc output_sample_desc
=
5537 .attributes
= output_sample_attributes
,
5538 .sample_time
= 0, .sample_duration
= 10000000,
5539 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
5542 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
5543 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
5544 DWORD i
, j
, k
, flags
, length
, output_status
;
5545 IMFSample
*input_sample
, *output_sample
;
5546 IMFMediaType
*media_type
, *media_type2
;
5547 const GUID
*expect_available_inputs
;
5548 IMFCollection
*output_samples
;
5549 const BYTE
*nv12frame_data
;
5550 ULONG nv12frame_data_len
;
5551 IMFTransform
*transform
;
5552 IMFMediaBuffer
*buffer
;
5559 hr
= CoInitialize(NULL
);
5560 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5562 winetest_push_context("videoproc");
5564 if (!check_mft_enum(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, class_id
))
5566 check_mft_get_info(class_id
, &expect_mft_info
);
5568 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5569 &IID_IMFTransform
, (void **)&transform
)))
5573 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
5575 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
5576 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
5577 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
5579 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
5580 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5582 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
5583 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5585 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5586 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5588 check_mft_get_input_current_type(transform
, NULL
);
5589 check_mft_get_output_current_type(transform
, NULL
);
5591 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
5592 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5594 /* Configure stream types. */
5597 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
5599 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5603 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
5604 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
5605 ok(media_type
!= media_type2
, "Unexpected instance.\n");
5606 ref
= IMFMediaType_Release(media_type2
);
5607 ok(ref
== 0, "Release returned %ld\n", ref
);
5609 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
5610 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5611 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
5613 hr
= IMFMediaType_GetCount(media_type
, &count
);
5614 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
5615 ok(count
== 2, "Unexpected count %u.\n", count
);
5617 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5618 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
5619 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
5621 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
5622 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
5624 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5625 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
5627 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
5628 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5630 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
5631 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
5632 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
5633 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
5635 ref
= IMFMediaType_Release(media_type
);
5636 ok(ref
== 0, "Release returned %ld\n", ref
);
5640 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
5641 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5643 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
5644 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
5646 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5647 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
5649 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
5650 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5651 ok(media_type
!= media_type2
, "Unexpected instance.\n");
5652 IMFMediaType_Release(media_type2
);
5654 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
5655 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5656 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
5658 input_info
.cbSize
= 0;
5659 if (!IsEqualGUID(&guid
, &MFVideoFormat_P208
) && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y41T
)
5660 && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y42T
))
5662 hr
= MFCalculateImageSize(&guid
, 16, 16, (UINT32
*)&input_info
.cbSize
);
5663 todo_wine_if(IsEqualGUID(&guid
, &MFVideoFormat_NV11
) || IsEqualGUID(&guid
, &MFVideoFormat_YVYU
)
5664 || IsEqualGUID(&guid
, &MFVideoFormat_Y216
) || IsEqualGUID(&guid
, &MFVideoFormat_v410
)
5665 || IsEqualGUID(&guid
, &MFVideoFormat_Y41P
))
5666 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5668 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5669 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5671 IMFMediaType_Release(media_type
);
5675 hr
= MFCreateMediaType(&media_type
);
5676 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5678 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5679 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5681 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
5682 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5684 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
5685 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5687 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5688 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5690 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5691 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5693 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
5694 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
5696 hr
= MFCalculateImageSize(&MFVideoFormat_IYUV
, 16, 16, (UINT32
*)&input_info
.cbSize
);
5697 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5698 hr
= MFCalculateImageSize(&MFVideoFormat_RGB32
, 16, 16, (UINT32
*)&output_info
.cbSize
);
5699 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5700 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5701 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5703 hr
= MFCreateSample(&input_sample
);
5704 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5706 hr
= MFCreateSample(&output_sample
);
5707 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5709 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5711 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
5713 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5715 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
5717 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5719 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
5721 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5723 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
5725 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5726 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
5727 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5729 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5731 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
5732 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
5734 hr
= IMFSample_AddBuffer(input_sample
, buffer
);
5735 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5737 hr
= IMFSample_AddBuffer(output_sample
, buffer
);
5738 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5740 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5742 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
5746 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5747 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
5750 ref
= IMFTransform_Release(transform
);
5751 ok(ref
== 0, "Release returned %ld\n", ref
);
5753 ref
= IMFMediaType_Release(media_type
);
5754 ok(ref
== 0, "Release returned %ld\n", ref
);
5755 ref
= IMFSample_Release(input_sample
);
5756 ok(ref
== 0, "Release returned %ld\n", ref
);
5757 ref
= IMFSample_Release(output_sample
);
5758 ok(ref
== 0, "Release returned %ld\n", ref
);
5759 ref
= IMFMediaBuffer_Release(buffer
);
5760 ok(ref
== 0, "Release returned %ld\n", ref
);
5763 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
5764 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5766 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5767 check_interface(transform
, &IID_IMediaObject
, FALSE
);
5768 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
5769 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
5771 check_mft_optional_methods(transform
, 1);
5772 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
5773 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
5774 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5776 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5777 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5779 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 23, &media_type
);
5780 ok(hr
== S_OK
|| hr
== MF_E_NO_MORE_TYPES
/* w8 */, "GetOutputAvailableType returned %#lx\n", hr
);
5781 if (hr
== MF_E_NO_MORE_TYPES
)
5782 expect_available_inputs
= expect_available_inputs_w8
;
5785 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 27, &media_type
);
5786 ok(hr
== S_OK
|| broken(hr
== MF_E_NO_MORE_TYPES
) /* w1064v1507 */, "GetOutputAvailableType returned %#lx\n", hr
);
5787 if (hr
== MF_E_NO_MORE_TYPES
)
5788 expect_available_inputs
= expect_available_inputs_w10
+ 3;
5790 expect_available_inputs
= expect_available_inputs_w10
;
5794 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5796 /* FIXME: Skip exotic input types which aren't directly accepted */
5797 if (IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L8
)
5798 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L16
)
5799 || IsEqualGUID(&expect_available_inputs
[i
], &MFAudioFormat_MPEG
)
5800 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_420O
)
5801 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_A16B16G16R16F
) /* w1064v1507 */)
5804 winetest_push_context("in %lu", i
);
5805 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5806 check_media_type(media_type
, expect_available_common
, -1);
5808 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5809 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
5811 /* w1064v1507 doesn't expose MFVideoFormat_ABGR32 input */
5812 if (broken(IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_ABGR32
)
5813 && IsEqualGUID(&guid
, &MFVideoFormat_RGB32
)))
5814 expect_available_inputs
++;
5816 ok(IsEqualGUID(&expect_available_inputs
[i
], &guid
), "got subtype %s\n", debugstr_guid(&guid
));
5818 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5819 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
5821 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)actual_width
<< 32 | actual_height
);
5822 ok(hr
== S_OK
, "SetUINT64 returned %#lx.\n", hr
);
5823 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5824 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5826 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type2
);
5827 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx.\n", hr
);
5828 hr
= IMFMediaType_IsEqual(media_type
, media_type2
, &flags
);
5829 ok(hr
== S_OK
, "IsEqual returned %#lx.\n", hr
);
5830 IMFMediaType_Release(media_type2
);
5832 ret
= IMFMediaType_Release(media_type
);
5833 ok(ret
== 1, "Release returned %lu\n", ret
);
5836 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++j
, &media_type
)))
5838 winetest_push_context("out %lu", j
);
5839 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5840 check_media_type(media_type
, expect_available_common
, -1);
5842 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5843 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
5845 for (; k
< ARRAY_SIZE(expect_available_outputs
); k
++)
5846 if (IsEqualGUID(&expect_available_outputs
[k
], &guid
))
5848 ok(k
< ARRAY_SIZE(expect_available_outputs
), "got subtype %s\n", debugstr_guid(&guid
));
5850 ret
= IMFMediaType_Release(media_type
);
5851 ok(ret
== 0, "Release returned %lu\n", ret
);
5852 winetest_pop_context();
5854 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5856 winetest_pop_context();
5858 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5859 ok(i
== 22 || i
== 30 || broken(i
== 26) /* w1064v1507 */, "%lu input media types\n", i
);
5861 check_mft_set_input_type_required(transform
, input_type_desc
);
5862 check_mft_set_input_type(transform
, input_type_desc
);
5863 check_mft_get_input_current_type(transform
, input_type_desc
);
5865 check_mft_set_output_type_required(transform
, output_type_desc
);
5866 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
5867 check_mft_get_output_current_type(transform
, output_type_desc
);
5869 input_info
.cbSize
= actual_width
* actual_height
* 3 / 2;
5870 output_info
.cbSize
= actual_width
* actual_height
* 4;
5871 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5872 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5874 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
5875 /* skip BMP header and RGB data from the dump */
5876 length
= *(DWORD
*)(nv12frame_data
+ 2);
5877 nv12frame_data_len
= nv12frame_data_len
- length
;
5878 nv12frame_data
= nv12frame_data
+ length
;
5879 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
5881 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
5882 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5883 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
5884 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
5885 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
5886 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5887 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5888 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5889 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5890 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
5891 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
5892 ret
= IMFSample_Release(input_sample
);
5893 ok(ret
<= 1, "Release returned %ld\n", ret
);
5895 hr
= MFCreateCollection(&output_samples
);
5896 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
5898 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5899 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5900 ok(hr
== S_OK
|| broken(hr
== MF_E_SHUTDOWN
) /* w8 */, "ProcessOutput returned %#lx\n", hr
);
5903 win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n");
5906 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5908 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5909 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5910 ref
= IMFSample_Release(output_sample
);
5911 ok(ref
== 1, "Release returned %ld\n", ref
);
5913 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame-vp.bmp");
5915 ok(ret
== 0 || broken(ret
== 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret
);
5916 IMFCollection_Release(output_samples
);
5918 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5919 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5920 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5921 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5922 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
5923 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
5924 ok(length
== 0, "got length %lu\n", length
);
5927 ret
= IMFSample_Release(output_sample
);
5928 ok(ret
== 0, "Release returned %lu\n", ret
);
5930 ret
= IMFTransform_Release(transform
);
5931 ok(ret
== 0, "Release returned %ld\n", ret
);
5934 winetest_pop_context();
5938 static void test_mp3_decoder(void)
5940 const GUID
*const class_id
= &CLSID_CMP3DecMediaObject
;
5941 const struct transform_info expect_mft_info
=
5943 .name
= L
"MP3 Decoder MFT",
5944 .major_type
= &MFMediaType_Audio
,
5947 {.subtype
= &MFAudioFormat_MP3
},
5951 {.subtype
= &MFAudioFormat_PCM
},
5954 const struct transform_info expect_dmo_info
=
5956 .name
= L
"MP3 Decoder DMO",
5957 .major_type
= &MEDIATYPE_Audio
,
5960 {.subtype
= &MFAudioFormat_MP3
},
5964 {.subtype
= &MEDIASUBTYPE_PCM
},
5968 static const ULONG mp3dec_block_size
= 0x1200;
5969 static const media_type_desc expect_available_inputs
[] =
5972 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5973 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
5974 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5977 static const media_type_desc expect_available_outputs
[] =
5980 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5981 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
5982 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
5983 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5984 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5985 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
5986 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
5987 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5990 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
5991 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
5992 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
5993 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
5994 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
5995 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
5996 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
5997 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6000 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6001 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6002 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
6003 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6004 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6005 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
6006 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
6007 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6010 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6011 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6012 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6013 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6014 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6015 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6016 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6017 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6020 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6021 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6022 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6023 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6024 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6025 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
6026 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
6027 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6030 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6031 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6032 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
6033 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6034 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6035 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050),
6036 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
6037 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6041 const struct attribute_desc input_type_desc
[] =
6043 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
6044 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
, .required
= TRUE
),
6045 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
6046 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6049 static const struct attribute_desc output_type_desc
[] =
6051 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
6052 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
6053 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
6054 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
6055 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
6056 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
6057 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
6060 const struct attribute_desc expect_input_type_desc
[] =
6062 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6063 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
6064 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6065 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6066 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6069 static const struct attribute_desc expect_output_type_desc
[] =
6071 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6072 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6073 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6074 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6075 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6076 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6077 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
6078 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6079 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6082 const MFT_OUTPUT_STREAM_INFO output_info
=
6084 .cbSize
= mp3dec_block_size
,
6087 const MFT_INPUT_STREAM_INFO input_info
=
6092 const struct buffer_desc output_buffer_desc
[] =
6094 {.length
= 0x9c0, .compare
= compare_pcm16
},
6095 {.length
= mp3dec_block_size
, .compare
= compare_pcm16
},
6097 const struct attribute_desc output_sample_attributes
[] =
6099 ATTR_UINT32(mft_output_sample_incomplete
, 1),
6100 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
6103 const struct sample_desc output_sample_desc
[] =
6106 .attributes
= output_sample_attributes
+ 0,
6107 .sample_time
= 0, .sample_duration
= 282993,
6108 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
6111 .attributes
= output_sample_attributes
+ 0,
6112 .sample_time
= 282993, .sample_duration
= 522449,
6113 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 18,
6116 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
6117 .sample_time
= 10209524, .sample_duration
= 522449,
6118 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1,
6122 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
6123 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_MP3
};
6124 IMFSample
*input_sample
, *output_sample
;
6125 IMFCollection
*output_samples
;
6126 DWORD length
, output_status
;
6127 IMFMediaType
*media_type
;
6128 IMFTransform
*transform
;
6129 const BYTE
*mp3enc_data
;
6130 ULONG mp3enc_data_len
;
6134 hr
= CoInitialize(NULL
);
6135 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6137 winetest_push_context("mp3dec");
6139 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
6141 check_mft_get_info(class_id
, &expect_mft_info
);
6142 check_dmo_get_info(class_id
, &expect_dmo_info
);
6144 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
6145 &IID_IMFTransform
, (void **)&transform
)))
6148 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6149 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6151 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6152 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
6154 check_mft_optional_methods(transform
, 1);
6155 check_mft_get_attributes(transform
, NULL
, FALSE
);
6156 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6157 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6159 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6160 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6163 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6165 winetest_push_context("in %lu", i
);
6166 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6167 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6168 ret
= IMFMediaType_Release(media_type
);
6169 ok(ret
== 0, "Release returned %lu\n", ret
);
6170 winetest_pop_context();
6173 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6175 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
6177 /* setting output media type first doesn't work */
6178 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
6179 check_mft_get_output_current_type(transform
, NULL
);
6181 check_mft_set_input_type_required(transform
, input_type_desc
);
6182 check_mft_set_input_type(transform
, input_type_desc
);
6183 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
6185 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6186 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6188 /* check new output media types */
6191 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6193 winetest_push_context("out %lu", i
);
6194 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6195 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6196 ret
= IMFMediaType_Release(media_type
);
6197 ok(ret
== 0, "Release returned %lu\n", ret
);
6198 winetest_pop_context();
6200 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6201 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
6203 check_mft_set_output_type_required(transform
, output_type_desc
);
6204 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
6205 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
6207 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6208 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6210 load_resource(L
"mp3encdata.bin", &mp3enc_data
, &mp3enc_data_len
);
6211 ok(mp3enc_data_len
== 6295, "got length %lu\n", mp3enc_data_len
);
6213 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
6214 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6215 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6216 ret
= IMFSample_Release(input_sample
);
6217 ok(ret
== 1, "Release returned %lu\n", ret
);
6219 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
6220 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6221 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6222 ret
= IMFSample_Release(input_sample
);
6223 ok(ret
== 0, "Release returned %lu\n", ret
);
6225 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6226 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6228 hr
= MFCreateCollection(&output_samples
);
6229 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
6231 /* first sample is broken */
6232 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6233 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6234 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6235 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
6236 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6237 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6238 ok(length
== mp3dec_block_size
/* Win8 */ || length
== 0x9c0 /* Win10 */ || length
== 0x900 /* Win7 */,
6239 "got length %lu\n", length
);
6240 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6241 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6242 ref
= IMFSample_Release(output_sample
);
6243 ok(ref
== 1, "Release returned %ld\n", ref
);
6245 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6246 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
6248 winetest_push_context("%lu", i
);
6249 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6250 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
6251 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6252 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6253 ref
= IMFSample_Release(output_sample
);
6254 ok(ref
== 1, "Release returned %ld\n", ref
);
6255 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6256 winetest_pop_context();
6258 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6259 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6260 ret
= IMFSample_Release(output_sample
);
6261 ok(ret
== 0, "Release returned %lu\n", ret
);
6262 ok(i
== 20 || broken(i
== 41) /* Win7 */, "got %lu output samples\n", i
);
6264 if (broken(length
!= 0x9c0))
6265 win_skip("Skipping MP3 decoder output sample checks on Win7 / Win8\n");
6268 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"mp3decdata.bin");
6269 ok(ret
== 0, "got %lu%% diff\n", ret
);
6271 IMFCollection_Release(output_samples
);
6273 output_sample
= create_sample(NULL
, mp3dec_block_size
);
6274 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6275 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6276 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6277 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6278 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6279 ok(length
== 0, "got length %lu\n", length
);
6280 ret
= IMFSample_Release(output_sample
);
6281 ok(ret
== 0, "Release returned %lu\n", ret
);
6283 ret
= IMFTransform_Release(transform
);
6284 ok(ret
== 0, "Release returned %lu\n", ret
);
6287 winetest_pop_context();
6291 START_TEST(transform
)
6295 test_sample_copier();
6296 test_sample_copier_output_processing();
6301 test_h264_decoder();
6304 test_wmv_decoder_media_object();
6305 test_audio_convert();
6306 test_color_convert();
6307 test_video_processor();