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 BOOL
is_compressed_subtype(const GUID
*subtype
)
60 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV1
)
61 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
62 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
63 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVP
)
64 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
65 || IsEqualGUID(subtype
, &MFVideoFormat_WMV_Unknown
)
66 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
67 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV3
)
68 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
73 static DWORD
subtype_to_compression(const GUID
*subtype
)
75 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB32
)
76 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB24
)
77 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB555
)
78 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
80 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
))
83 return subtype
->Data1
;
86 static DWORD
subtype_to_bpp(const GUID
*subtype
)
88 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
90 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_NV12
)
91 || IsEqualGUID(subtype
, &MEDIASUBTYPE_YV12
)
92 || IsEqualGUID(subtype
, &MEDIASUBTYPE_IYUV
)
93 || IsEqualGUID(subtype
, &MEDIASUBTYPE_I420
)
94 || IsEqualGUID(subtype
, &MEDIASUBTYPE_NV11
))
96 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_YUY2
)
97 || IsEqualGUID(subtype
, &MEDIASUBTYPE_UYVY
)
98 || IsEqualGUID(subtype
, &MEDIASUBTYPE_YVYU
)
99 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
)
100 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB555
))
102 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB24
))
104 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB32
))
110 static void load_resource(const WCHAR
*filename
, const BYTE
**data
, DWORD
*length
)
112 HRSRC resource
= FindResourceW(NULL
, filename
, (const WCHAR
*)RT_RCDATA
);
113 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
114 *data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
115 *length
= SizeofResource(GetModuleHandleW(NULL
), resource
);
118 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
119 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
122 IUnknown_AddRef(obj
);
123 refcount
= IUnknown_Release(obj
);
124 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
128 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
129 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
131 IUnknown
*iface
= iface_ptr
;
132 HRESULT hr
, expected_hr
;
135 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
137 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
138 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
140 IUnknown_Release(unk
);
143 #define check_member_(file, line, val, exp, fmt, member) \
144 ok_ (file, line)((val).member == (exp).member, "got " #member " " fmt "\n", (val).member)
145 #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
147 void check_attributes_(const char *file
, int line
, IMFAttributes
*attributes
,
148 const struct attribute_desc
*desc
, ULONG limit
)
150 char buffer
[256], *buf
= buffer
;
155 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
157 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
158 todo_wine_if(desc
[i
].todo
)
159 ok_(file
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
160 if (hr
!= S_OK
) continue;
164 default: sprintf(buffer
, "??"); break;
165 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
166 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
169 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
171 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
173 case VT_VECTOR
| VT_UI1
:
174 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
175 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
176 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
177 if (value
.caub
.cElems
> 16)
178 buf
+= sprintf(buf
, "...}");
180 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
184 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
185 todo_wine_if(desc
[i
].todo_value
)
186 ok_(file
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
187 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
191 struct transform_info
194 const GUID
*major_type
;
199 } inputs
[32], input_end
, outputs
[32], output_end
;
202 static BOOL
check_mft_enum(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
203 MFT_REGISTER_TYPE_INFO
*output_type
, const GUID
*expect_class_id
)
205 GUID
*class_ids
= NULL
;
209 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
210 if (FAILED(hr
) || count
== 0)
213 win_skip("MFTEnum returned %#lx, count %u, skipping tests.\n", hr
, count
);
217 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
218 for (i
= 0; i
< count
; ++i
)
219 if (IsEqualGUID(expect_class_id
, class_ids
+ i
))
221 ok(i
< count
, "Failed to find transform.\n");
222 CoTaskMemFree(class_ids
);
227 static void check_mft_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
229 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
230 UINT32 input_count
= 0, output_count
= 0, i
;
234 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
235 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
236 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
238 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
240 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect
->major_type
),
241 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
242 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect
->inputs
[i
].subtype
),
243 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
245 for (; expect
->inputs
[i
].subtype
; ++i
)
246 ok(broken(expect
->inputs
[i
].broken
), "missing input[%u] subtype %s\n",
247 i
, debugstr_guid(expect
->inputs
[i
].subtype
));
248 for (; i
< input_count
; ++i
)
249 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
251 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
253 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect
->major_type
),
254 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
255 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect
->outputs
[i
].subtype
),
256 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
258 for (; expect
->outputs
[i
].subtype
; ++i
)
259 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
260 for (; i
< output_count
; ++i
)
261 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
263 CoTaskMemFree(output_types
);
264 CoTaskMemFree(input_types
);
268 static void check_dmo_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
270 DWORD input_count
= 0, output_count
= 0;
271 DMO_PARTIAL_MEDIATYPE output
[32] = {{{0}}};
272 DMO_PARTIAL_MEDIATYPE input
[32] = {{{0}}};
277 hr
= DMOGetName(class_id
, name
);
278 ok(hr
== S_OK
, "DMOGetName returned %#lx\n", hr
);
279 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
281 hr
= DMOGetTypes(class_id
, ARRAY_SIZE(input
), &input_count
, input
,
282 ARRAY_SIZE(output
), &output_count
, output
);
283 ok(hr
== S_OK
, "DMOGetTypes returned %#lx\n", hr
);
285 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
287 ok(IsEqualGUID(&input
[i
].type
, expect
->major_type
),
288 "got input[%u] major %s\n", i
, debugstr_guid(&input
[i
].type
));
289 ok(IsEqualGUID(&input
[i
].subtype
, expect
->inputs
[i
].subtype
),
290 "got input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
292 for (; expect
->inputs
[i
].subtype
; ++i
)
293 ok(0, "missing input[%u] subtype %s\n", i
, debugstr_guid(expect
->inputs
[i
].subtype
));
294 for (; i
< input_count
; ++i
)
295 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
297 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
299 ok(IsEqualGUID(&output
[i
].type
, expect
->major_type
),
300 "got output[%u] major %s\n", i
, debugstr_guid(&output
[i
].type
));
301 ok(IsEqualGUID(&output
[i
].subtype
, expect
->outputs
[i
].subtype
),
302 "got output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
304 for (; expect
->outputs
[i
].subtype
; ++i
)
305 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
306 for (; i
< output_count
; ++i
)
307 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
310 void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
315 hr
= IMFMediaType_DeleteAllItems(mediatype
);
316 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
318 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
320 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
321 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
325 static void init_dmo_media_type_video(DMO_MEDIA_TYPE
*media_type
,
326 const GUID
*subtype
, const LONG width
, const LONG height
)
328 VIDEOINFOHEADER
*header
= (VIDEOINFOHEADER
*)(media_type
+ 1);
329 BOOL compressed
= is_compressed_subtype(subtype
);
331 memset(header
, 0, sizeof(*header
));
332 header
->bmiHeader
.biSize
= sizeof(header
->bmiHeader
);
333 header
->bmiHeader
.biWidth
= width
;
334 header
->bmiHeader
.biHeight
= height
;
335 header
->bmiHeader
.biBitCount
= subtype_to_bpp(subtype
);
336 header
->bmiHeader
.biCompression
= subtype_to_compression(subtype
);
338 media_type
->majortype
= MEDIATYPE_Video
;
339 media_type
->subtype
= *subtype
;
340 media_type
->bFixedSizeSamples
= !compressed
;
341 media_type
->bTemporalCompression
= compressed
;
342 media_type
->lSampleSize
= 0;
343 media_type
->formattype
= FORMAT_VideoInfo
;
344 media_type
->pUnk
= NULL
;
345 media_type
->cbFormat
= sizeof(*header
) + 4; /* 4 bytes codec data. */
346 media_type
->pbFormat
= (BYTE
*)header
;
349 static void check_mft_optional_methods(IMFTransform
*transform
, DWORD output_count
)
351 DWORD in_id
, out_id
, in_count
, out_count
, in_min
, in_max
, out_min
, out_max
;
352 PROPVARIANT propvar
= {.vt
= VT_EMPTY
};
353 IMFMediaEvent
*event
;
356 in_min
= in_max
= out_min
= out_max
= 0xdeadbeef;
357 hr
= IMFTransform_GetStreamLimits(transform
, &in_min
, &in_max
, &out_min
, &out_max
);
358 ok(hr
== S_OK
, "GetStreamLimits returned %#lx\n", hr
);
359 ok(in_min
== 1, "got input_min %lu\n", in_min
);
360 ok(in_max
== 1, "got input_max %lu\n", in_max
);
361 ok(out_min
== output_count
, "got output_min %lu\n", out_min
);
362 ok(out_max
== output_count
, "got output_max %lu\n", out_max
);
364 in_count
= out_count
= 0xdeadbeef;
365 hr
= IMFTransform_GetStreamCount(transform
, &in_count
, &out_count
);
366 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
367 ok(in_count
== 1, "got input_count %lu\n", in_count
);
368 ok(out_count
== output_count
, "got output_count %lu\n", out_count
);
370 in_count
= out_count
= 1;
371 in_id
= out_id
= 0xdeadbeef;
372 hr
= IMFTransform_GetStreamIDs(transform
, in_count
, &in_id
, out_count
, &out_id
);
373 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
375 hr
= IMFTransform_DeleteInputStream(transform
, 0);
376 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
377 hr
= IMFTransform_DeleteInputStream(transform
, 1);
378 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
380 hr
= IMFTransform_AddInputStreams(transform
, 0, NULL
);
381 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
383 hr
= IMFTransform_AddInputStreams(transform
, 1, &in_id
);
384 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
386 hr
= IMFTransform_SetOutputBounds(transform
, 0, 0);
387 ok(hr
== E_NOTIMPL
|| hr
== S_OK
, "SetOutputBounds returned %#lx\n", hr
);
389 hr
= MFCreateMediaEvent(MEEndOfStream
, &GUID_NULL
, S_OK
, &propvar
, &event
);
390 ok(hr
== S_OK
, "MFCreateMediaEvent returned %#lx\n", hr
);
391 hr
= IMFTransform_ProcessEvent(transform
, 0, NULL
);
392 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
|| hr
== E_INVALIDARG
, "ProcessEvent returned %#lx\n", hr
);
393 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
394 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
395 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
396 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
397 IMFMediaEvent_Release(event
);
400 static void check_mft_get_attributes(IMFTransform
*transform
, const struct attribute_desc
*expect_transform_attributes
,
401 BOOL expect_output_attributes
)
403 IMFAttributes
*attributes
, *tmp_attributes
;
408 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
409 todo_wine_if(expect_transform_attributes
&& hr
== E_NOTIMPL
)
410 ok(hr
== (expect_transform_attributes
? S_OK
: E_NOTIMPL
), "GetAttributes returned %#lx\n", hr
);
413 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
414 check_attributes(attributes
, expect_transform_attributes
, -1);
416 hr
= IMFTransform_GetAttributes(transform
, &tmp_attributes
);
417 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
418 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
419 IMFAttributes_Release(tmp_attributes
);
421 ref
= IMFAttributes_Release(attributes
);
422 ok(ref
== 1, "Release returned %lu\n", ref
);
425 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
426 todo_wine_if(expect_output_attributes
&& hr
== E_NOTIMPL
)
427 ok(hr
== (expect_output_attributes
? S_OK
: E_NOTIMPL
)
428 || broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
429 "GetOutputStreamAttributes returned %#lx\n", hr
);
432 ok(hr
== S_OK
, "GetOutputStreamAttributes returned %#lx\n", hr
);
435 hr
= IMFAttributes_GetCount(attributes
, &count
);
436 ok(hr
== S_OK
, "GetCount returned %#lx\n", hr
);
437 ok(!count
, "got %u attributes\n", count
);
439 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &tmp_attributes
);
440 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
441 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
442 IMFAttributes_Release(tmp_attributes
);
444 ref
= IMFAttributes_Release(attributes
);
445 ok(ref
== 1, "Release returned %lu\n", ref
);
447 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, NULL
);
448 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
449 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 1, &attributes
);
450 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
453 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
454 ok(hr
== E_NOTIMPL
|| broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
455 "GetInputStreamAttributes returned %#lx\n", hr
);
458 #define check_mft_input_stream_info(a, b) check_mft_input_stream_info_(__LINE__, a, b)
459 static void check_mft_input_stream_info_(int line
, MFT_INPUT_STREAM_INFO
*value
, const MFT_INPUT_STREAM_INFO
*expect
)
461 check_member_(__FILE__
, line
, *value
, *expect
, "%I64d", hnsMaxLatency
);
462 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
463 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
464 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbMaxLookahead
);
465 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
468 #define check_mft_get_input_stream_info(a, b, c) check_mft_get_input_stream_info_(__LINE__, a, b, c)
469 static void check_mft_get_input_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_INPUT_STREAM_INFO
*expect
)
471 MFT_INPUT_STREAM_INFO info
, empty
= {0};
474 memset(&info
, 0xcd, sizeof(info
));
475 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &info
);
476 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetInputStreamInfo returned %#lx\n", hr
);
477 check_mft_input_stream_info_(line
, &info
, expect
? expect
: &empty
);
480 #define check_mft_output_stream_info(a, b) check_mft_output_stream_info_(__LINE__, a, b)
481 static void check_mft_output_stream_info_(int line
, MFT_OUTPUT_STREAM_INFO
*value
, const MFT_OUTPUT_STREAM_INFO
*expect
)
483 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
484 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
485 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
488 #define check_mft_get_output_stream_info(a, b, c) check_mft_get_output_stream_info_(__LINE__, a, b, c)
489 static void check_mft_get_output_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_OUTPUT_STREAM_INFO
*expect
)
491 MFT_OUTPUT_STREAM_INFO info
, empty
= {0};
494 memset(&info
, 0xcd, sizeof(info
));
495 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
496 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetOutputStreamInfo returned %#lx\n", hr
);
497 check_mft_output_stream_info_(line
, &info
, expect
? expect
: &empty
);
500 #define check_mft_set_input_type_required(a, b) check_mft_set_input_type_required_(__LINE__, a, b)
501 static void check_mft_set_input_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
503 const struct attribute_desc
*attr
;
504 IMFMediaType
*media_type
;
508 hr
= MFCreateMediaType(&media_type
);
509 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
510 init_media_type(media_type
, attributes
, -1);
512 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
514 winetest_push_context("%s", debugstr_a(attr
->name
));
515 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
516 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
517 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
518 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetInputType returned %#lx.\n", hr
);
519 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
520 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
521 winetest_pop_context();
524 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
525 ok_(__FILE__
, line
)(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
526 ref
= IMFMediaType_Release(media_type
);
527 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
530 static void check_mft_set_input_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
)
532 IMFMediaType
*media_type
;
535 hr
= MFCreateMediaType(&media_type
);
536 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
537 init_media_type(media_type
, attributes
, -1);
539 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
540 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
541 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
542 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
544 IMFMediaType_Release(media_type
);
547 #define check_mft_get_input_current_type(a, b) check_mft_get_input_current_type_(a, b, FALSE, FALSE)
548 static void check_mft_get_input_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
549 BOOL todo_current
, BOOL todo_compare
)
551 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
552 IMFMediaType
*media_type
, *current_type
;
555 hr
= IMFTransform_GetInputCurrentType(transform
, 0, ¤t_type
);
556 todo_wine_if(todo_current
)
557 ok(hr
== expect_hr
, "GetInputCurrentType returned hr %#lx.\n", hr
);
561 hr
= MFCreateMediaType(&media_type
);
562 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
563 init_media_type(media_type
, attributes
, -1);
565 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
566 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
567 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
568 todo_wine_if(todo_compare
)
569 ok(result
, "got result %u.\n", !!result
);
571 IMFMediaType_Release(media_type
);
572 IMFMediaType_Release(current_type
);
575 #define check_mft_set_output_type_required(a, b) check_mft_set_output_type_required_(__LINE__, a, b)
576 static void check_mft_set_output_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
578 const struct attribute_desc
*attr
;
579 IMFMediaType
*media_type
;
583 hr
= MFCreateMediaType(&media_type
);
584 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
585 init_media_type(media_type
, attributes
, -1);
587 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
589 winetest_push_context("%s", debugstr_a(attr
->name
));
590 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
591 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
592 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
593 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetOutputType returned %#lx.\n", hr
);
594 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
595 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
596 winetest_pop_context();
599 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
600 ok_(__FILE__
, line
)(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
601 ref
= IMFMediaType_Release(media_type
);
602 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
605 static void check_mft_set_output_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
608 IMFMediaType
*media_type
;
611 hr
= MFCreateMediaType(&media_type
);
612 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
613 init_media_type(media_type
, attributes
, -1);
615 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
616 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
617 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
618 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
620 IMFMediaType_Release(media_type
);
623 #define check_mft_get_output_current_type(a, b) check_mft_get_output_current_type_(a, b, FALSE, FALSE)
624 static void check_mft_get_output_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
625 BOOL todo_current
, BOOL todo_compare
)
627 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
628 IMFMediaType
*media_type
, *current_type
;
631 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, ¤t_type
);
632 todo_wine_if(todo_current
)
633 ok(hr
== expect_hr
, "GetOutputCurrentType returned hr %#lx.\n", hr
);
637 hr
= MFCreateMediaType(&media_type
);
638 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
639 init_media_type(media_type
, attributes
, -1);
641 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
642 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
643 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
644 todo_wine_if(todo_compare
)
645 ok(result
, "got result %u.\n", !!result
);
647 IMFMediaType_Release(media_type
);
648 IMFMediaType_Release(current_type
);
651 #define check_mft_process_output(a, b, c) check_mft_process_output_(__LINE__, a, b, c)
652 static HRESULT
check_mft_process_output_(int line
, IMFTransform
*transform
, IMFSample
*output_sample
, DWORD
*output_status
)
654 static const DWORD expect_flags
= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
| MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
655 | MFT_OUTPUT_DATA_BUFFER_STREAM_END
| MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
656 MFT_OUTPUT_DATA_BUFFER output
[3];
661 memset(&output
, 0, sizeof(output
));
662 output
[0].pSample
= output_sample
;
663 output
[0].dwStreamID
= 0;
664 ret
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
665 ok_(__FILE__
, line
)(output
[0].dwStreamID
== 0, "got dwStreamID %#lx\n", output
[0].dwStreamID
);
666 ok_(__FILE__
, line
)(output
[0].pEvents
== NULL
, "got pEvents %p\n", output
[0].pEvents
);
667 ok_(__FILE__
, line
)(output
[0].pSample
== output_sample
, "got pSample %p\n", output
[0].pSample
);
668 ok_(__FILE__
, line
)((output
[0].dwStatus
& ~expect_flags
) == 0
669 || broken((output
[0].dwStatus
& ~expect_flags
) == 6) /* Win7 */
670 || broken((output
[0].dwStatus
& ~expect_flags
) == 7) /* Win7 */,
671 "got dwStatus %#lx\n", output
[0].dwStatus
);
672 *output_status
= output
[0].dwStatus
& expect_flags
;
675 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
676 else if (ret
== MF_E_TRANSFORM_STREAM_CHANGE
)
677 ok_(__FILE__
, line
)(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
678 "got status %#lx\n", status
);
681 if (*output_status
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
)
683 hr
= IMFSample_SetUINT32(output_sample
, &mft_output_sample_incomplete
, 1);
684 ok_(__FILE__
, line
)(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
688 hr
= IMFSample_DeleteItem(output_sample
, &mft_output_sample_incomplete
);
689 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
691 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
697 DWORD
compare_nv12(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
699 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
701 /* skip BMP header and RGB data from the dump */
702 size
= *(DWORD
*)(expect
+ 2);
703 *length
= *length
+ size
;
704 expect
= expect
+ size
;
706 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
708 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
709 for (x
= 0; x
< width
; x
++)
711 if (x
< rect
->left
|| x
>= rect
->right
) continue;
712 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
716 for (y
= 0; y
< height
; y
+= 2, data
+= width
, expect
+= width
)
718 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
719 for (x
= 0; x
< width
; x
+= 2)
721 if (x
< rect
->left
|| x
>= rect
->right
) continue;
722 diff
+= abs((int)expect
[x
+ 0] - (int)data
[x
+ 0]);
723 diff
+= abs((int)expect
[x
+ 1] - (int)data
[x
+ 1]);
727 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
728 return diff
* 100 / 256 / size
;
731 DWORD
compare_i420(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
733 DWORD i
, x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
735 /* skip BMP header and RGB data from the dump */
736 size
= *(DWORD
*)(expect
+ 2);
737 *length
= *length
+ size
;
738 expect
= expect
+ size
;
740 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
742 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
743 for (x
= 0; x
< width
; x
++)
745 if (x
< rect
->left
|| x
>= rect
->right
) continue;
746 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
750 for (i
= 0; i
< 2; ++i
) for (y
= 0; y
< height
; y
+= 2, data
+= width
/ 2, expect
+= width
/ 2)
752 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
753 for (x
= 0; x
< width
; x
+= 2)
755 if (x
< rect
->left
|| x
>= rect
->right
) continue;
756 diff
+= abs((int)expect
[x
/ 2] - (int)data
[x
/ 2]);
760 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
761 return diff
* 100 / 256 / size
;
764 DWORD
compare_rgb32(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
766 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
768 /* skip BMP header from the dump */
769 size
= *(DWORD
*)(expect
+ 2 + 2 * sizeof(DWORD
));
770 *length
= *length
+ size
;
771 expect
= expect
+ size
;
773 for (y
= 0; y
< height
; y
++, data
+= width
* 4, expect
+= width
* 4)
775 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
776 for (x
= 0; x
< width
; x
++)
778 if (x
< rect
->left
|| x
>= rect
->right
) continue;
779 diff
+= abs((int)expect
[4 * x
+ 0] - (int)data
[4 * x
+ 0]);
780 diff
+= abs((int)expect
[4 * x
+ 1] - (int)data
[4 * x
+ 1]);
781 diff
+= abs((int)expect
[4 * x
+ 2] - (int)data
[4 * x
+ 2]);
785 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3;
786 return diff
* 100 / 256 / size
;
789 DWORD
compare_pcm16(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
791 const INT16
*data_pcm
= (INT16
*)data
, *expect_pcm
= (INT16
*)expect
;
792 DWORD i
, size
= *length
/ 2, diff
= 0;
794 for (i
= 0; i
< size
; i
++)
795 diff
+= abs((int)*expect_pcm
++ - (int)*data_pcm
++);
797 return diff
* 100 / 65536 / size
;
800 static DWORD
compare_bytes(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
802 DWORD i
, size
= *length
, diff
= 0;
804 for (i
= 0; i
< size
; i
++)
805 diff
+= abs((int)*expect
++ - (int)*data
++);
807 return diff
* 100 / 256 / size
;
810 void dump_rgb32(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
812 DWORD width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
813 static const char magic
[2] = "BM";
819 BITMAPINFOHEADER biHeader
;
822 .length
= length
+ sizeof(header
) + 2, .offset
= sizeof(header
) + 2,
825 .biSize
= sizeof(BITMAPINFOHEADER
), .biWidth
= width
, .biHeight
= height
, .biPlanes
= 1,
826 .biBitCount
= 32, .biCompression
= BI_RGB
, .biSizeImage
= width
* height
* 4,
832 ret
= WriteFile(output
, magic
, sizeof(magic
), &written
, NULL
);
833 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
834 ok(written
== sizeof(magic
), "written %lu bytes\n", written
);
835 ret
= WriteFile(output
, &header
, sizeof(header
), &written
, NULL
);
836 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
837 ok(written
== sizeof(header
), "written %lu bytes\n", written
);
838 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
839 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
840 ok(written
== length
, "written %lu bytes\n", written
);
843 void dump_nv12(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
845 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
846 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
849 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
851 *rgb32
++ = data
[width
* y
+ x
];
852 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 0];
853 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 1];
857 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
860 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
861 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
862 ok(written
== length
, "written %lu bytes\n", written
);
865 void dump_i420(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
867 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
868 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
871 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
873 *rgb32
++ = data
[width
* y
+ x
];
874 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + x
/ 2];
875 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + (width
/ 2) * (height
/ 2) + x
/ 2];
879 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
882 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
883 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
884 ok(written
== length
, "written %lu bytes\n", written
);
887 typedef void (*enum_mf_media_buffers_cb
)(IMFMediaBuffer
*buffer
, const struct buffer_desc
*desc
, void *context
);
888 static void enum_mf_media_buffers(IMFSample
*sample
, const struct sample_desc
*sample_desc
,
889 enum_mf_media_buffers_cb callback
, void *context
)
891 IMFMediaBuffer
*buffer
;
895 for (i
= 0; SUCCEEDED(hr
= IMFSample_GetBufferByIndex(sample
, i
, &buffer
)); i
++)
897 winetest_push_context("buffer %lu", i
);
898 ok(hr
== S_OK
, "GetBufferByIndex returned %#lx\n", hr
);
899 ok(i
< sample_desc
->buffer_count
, "got unexpected buffer\n");
901 callback(buffer
, sample_desc
->buffers
+ i
, context
);
903 IMFMediaBuffer_Release(buffer
);
904 winetest_pop_context();
906 ok(hr
== E_INVALIDARG
, "GetBufferByIndex returned %#lx\n", hr
);
909 struct enum_mf_sample_state
911 const struct sample_desc
*next_sample
;
912 struct sample_desc sample
;
915 typedef void (*enum_mf_sample_cb
)(IMFSample
*sample
, const struct sample_desc
*sample_desc
, void *context
);
916 static void enum_mf_samples(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
917 enum_mf_sample_cb callback
, void *context
)
919 struct enum_mf_sample_state state
= {.next_sample
= collection_desc
};
924 for (i
= 0; SUCCEEDED(hr
= IMFCollection_GetElement(samples
, i
, (IUnknown
**)&sample
)); i
++)
926 winetest_push_context("sample %lu", i
);
927 ok(hr
== S_OK
, "GetElement returned %#lx\n", hr
);
929 state
.sample
.sample_time
+= state
.sample
.sample_duration
;
930 if (!state
.sample
.repeat_count
--)
931 state
.sample
= *state
.next_sample
++;
933 callback(sample
, &state
.sample
, context
);
935 IMFSample_Release(sample
);
936 winetest_pop_context();
938 ok(hr
== E_INVALIDARG
, "GetElement returned %#lx\n", hr
);
941 static void dump_mf_media_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*buffer_desc
, HANDLE output
)
943 DWORD length
, written
;
948 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
949 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
951 if (buffer_desc
->dump
)
952 buffer_desc
->dump(data
, length
, &buffer_desc
->rect
, output
);
955 if (buffer_desc
->length
== -1)
957 ret
= WriteFile(output
, &length
, sizeof(length
), &written
, NULL
);
958 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
959 ok(written
== sizeof(length
), "written %lu bytes\n", written
);
962 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
963 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
964 ok(written
== length
, "written %lu bytes\n", written
);
967 hr
= IMFMediaBuffer_Unlock(buffer
);
968 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
971 static void dump_mf_sample(IMFSample
*sample
, const struct sample_desc
*sample_desc
, HANDLE output
)
973 enum_mf_media_buffers(sample
, sample_desc
, dump_mf_media_buffer
, output
);
976 static void dump_mf_sample_collection(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
977 const WCHAR
*output_filename
)
979 WCHAR path
[MAX_PATH
];
982 GetTempPathW(ARRAY_SIZE(path
), path
);
983 lstrcatW(path
, output_filename
);
985 output
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
986 ok(output
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
988 enum_mf_samples(samples
, collection_desc
, dump_mf_sample
, output
);
990 trace("created %s\n", debugstr_w(path
));
994 #define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__FILE__, __LINE__, a, b, c)
995 static DWORD
check_mf_media_buffer_(const char *file
, int line
, IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
,
996 const BYTE
**expect_data
, DWORD
*expect_data_len
)
998 DWORD length
, diff
= 0, expect_length
= expect
->length
;
1002 if (expect_length
== -1)
1004 expect_length
= *(DWORD
*)*expect_data
;
1005 *expect_data
= *expect_data
+ sizeof(DWORD
);
1006 *expect_data_len
= *expect_data_len
- sizeof(DWORD
);
1009 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
1010 ok_(file
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
1011 todo_wine_if(expect
->todo_length
)
1012 ok_(file
, line
)(length
== expect_length
, "got length %#lx\n", length
);
1014 if (*expect_data_len
< length
)
1015 todo_wine_if(expect
->todo_length
)
1016 ok_(file
, line
)(0, "missing %#lx bytes\n", length
- *expect_data_len
);
1017 else if (!expect
->compare
)
1018 diff
= compare_bytes(data
, &length
, NULL
, *expect_data
);
1020 diff
= expect
->compare(data
, &length
, &expect
->rect
, *expect_data
);
1022 hr
= IMFMediaBuffer_Unlock(buffer
);
1023 ok_(file
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
1025 *expect_data
= *expect_data
+ min(length
, *expect_data_len
);
1026 *expect_data_len
= *expect_data_len
- min(length
, *expect_data_len
);
1031 struct check_mf_sample_context
1041 static void check_mf_sample_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
, void *context
)
1043 struct check_mf_sample_context
*ctx
= context
;
1044 DWORD expect_length
= expect
->length
== -1 ? *(DWORD
*)ctx
->data
: expect
->length
;
1045 ctx
->diff
+= check_mf_media_buffer_(ctx
->file
, ctx
->line
, buffer
, expect
, &ctx
->data
, &ctx
->data_len
);
1046 ctx
->total_length
+= expect_length
;
1049 #define check_mf_sample(a, b, c, d) check_mf_sample_(__FILE__, __LINE__, a, b, c, d)
1050 static DWORD
check_mf_sample_(const char *file
, int line
, IMFSample
*sample
, const struct sample_desc
*expect
,
1051 const BYTE
**expect_data
, DWORD
*expect_data_len
)
1053 struct check_mf_sample_context ctx
= {.data
= *expect_data
, .data_len
= *expect_data_len
, .file
= file
, .line
= line
};
1054 DWORD buffer_count
, total_length
, sample_flags
;
1058 if (expect
->attributes
)
1059 check_attributes_(file
, line
, (IMFAttributes
*)sample
, expect
->attributes
, -1);
1061 buffer_count
= 0xdeadbeef;
1062 hr
= IMFSample_GetBufferCount(sample
, &buffer_count
);
1063 ok_(file
, line
)(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
1064 ok_(file
, line
)(buffer_count
== expect
->buffer_count
,
1065 "got %lu buffers\n", buffer_count
);
1067 sample_flags
= 0xdeadbeef;
1068 hr
= IMFSample_GetSampleFlags(sample
, &sample_flags
);
1069 ok_(file
, line
)(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
1070 ok_(file
, line
)(sample_flags
== 0,
1071 "got sample flags %#lx\n", sample_flags
);
1073 timestamp
= 0xdeadbeef;
1074 hr
= IMFSample_GetSampleTime(sample
, ×tamp
);
1075 ok_(file
, line
)(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
1076 todo_wine_if(expect
->todo_time
&& timestamp
== expect
->todo_time
)
1077 ok_(file
, line
)(llabs(timestamp
- expect
->sample_time
) <= 50,
1078 "got sample time %I64d\n", timestamp
);
1080 timestamp
= 0xdeadbeef;
1081 hr
= IMFSample_GetSampleDuration(sample
, ×tamp
);
1082 ok_(file
, line
)(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
1083 todo_wine_if(expect
->todo_length
)
1084 ok_(file
, line
)(llabs(timestamp
- expect
->sample_duration
) <= 1,
1085 "got sample duration %I64d\n", timestamp
);
1087 enum_mf_media_buffers(sample
, expect
, check_mf_sample_buffer
, &ctx
);
1089 total_length
= 0xdeadbeef;
1090 hr
= IMFSample_GetTotalLength(sample
, &total_length
);
1091 ok_(file
, line
)(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1092 todo_wine_if(expect
->todo_length
)
1093 ok_(file
, line
)(total_length
== ctx
.total_length
,
1094 "got total length %#lx\n", total_length
);
1095 ok_(file
, line
)(*expect_data_len
>= ctx
.total_length
,
1096 "missing %#lx data\n", ctx
.total_length
- *expect_data_len
);
1098 *expect_data
= ctx
.data
;
1099 *expect_data_len
= ctx
.data_len
;
1101 return ctx
.diff
/ buffer_count
;
1104 static void check_mf_sample_collection_enum(IMFSample
*sample
, const struct sample_desc
*expect
, void *context
)
1106 struct check_mf_sample_context
*ctx
= context
;
1107 ctx
->diff
+= check_mf_sample_(ctx
->file
, ctx
->line
, sample
, expect
, &ctx
->data
, &ctx
->data_len
);
1110 DWORD
check_mf_sample_collection_(const char *file
, int line
, IMFCollection
*samples
,
1111 const struct sample_desc
*expect_samples
, const WCHAR
*expect_data_filename
)
1113 struct check_mf_sample_context ctx
= {.file
= file
, .line
= line
};
1117 load_resource(expect_data_filename
, &ctx
.data
, &ctx
.data_len
);
1118 enum_mf_samples(samples
, expect_samples
, check_mf_sample_collection_enum
, &ctx
);
1120 dump_mf_sample_collection(samples
, expect_samples
, expect_data_filename
);
1122 hr
= IMFCollection_GetElementCount(samples
, &count
);
1123 ok_(file
, line
)(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
1125 return ctx
.diff
/ count
;
1128 #define check_video_info_header(a, b) check_video_info_header_(__LINE__, a, b)
1129 static void check_video_info_header_(int line
, VIDEOINFOHEADER
*info
, const VIDEOINFOHEADER
*expected
)
1131 ok_(__FILE__
, line
)(info
->rcSource
.left
== expected
->rcSource
.left
1132 && info
->rcSource
.top
== expected
->rcSource
.top
1133 && info
->rcSource
.right
== expected
->rcSource
.right
1134 && info
->rcSource
.bottom
== expected
->rcSource
.bottom
,
1135 "Got unexpected rcSource {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1136 info
->rcSource
.left
, info
->rcSource
.top
, info
->rcSource
.right
, info
->rcSource
.bottom
,
1137 expected
->rcSource
.left
, expected
->rcSource
.top
, expected
->rcSource
.right
, expected
->rcSource
.bottom
);
1138 ok_(__FILE__
, line
)(info
->rcTarget
.left
== expected
->rcTarget
.left
1139 && info
->rcTarget
.top
== expected
->rcTarget
.top
1140 && info
->rcTarget
.right
== expected
->rcTarget
.right
1141 && info
->rcTarget
.bottom
== expected
->rcTarget
.bottom
,
1142 "Got unexpected rcTarget {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1143 info
->rcTarget
.left
, info
->rcTarget
.top
, info
->rcTarget
.right
, info
->rcTarget
.bottom
,
1144 expected
->rcTarget
.left
, expected
->rcTarget
.top
, expected
->rcTarget
.right
, expected
->rcTarget
.bottom
);
1145 ok_(__FILE__
, line
)(info
->dwBitRate
== expected
->dwBitRate
,
1146 "Got unexpected dwBitRate %lu, expected %lu.\n",
1147 info
->dwBitRate
, expected
->dwBitRate
);
1148 ok_(__FILE__
, line
)(info
->dwBitErrorRate
== expected
->dwBitErrorRate
,
1149 "Got unexpected dwBitErrorRate %lu, expected %lu.\n",
1150 info
->dwBitErrorRate
, expected
->dwBitErrorRate
);
1151 ok_(__FILE__
, line
)(info
->AvgTimePerFrame
== expected
->AvgTimePerFrame
,
1152 "Got unexpected AvgTimePerFrame %I64d, expected %I64d.\n",
1153 info
->AvgTimePerFrame
, expected
->AvgTimePerFrame
);
1154 ok_(__FILE__
, line
)(info
->bmiHeader
.biSize
== expected
->bmiHeader
.biSize
,
1155 "Got unexpected bmiHeader.biSize %lu, expected %lu.\n",
1156 info
->bmiHeader
.biSize
, expected
->bmiHeader
.biSize
);
1157 ok_(__FILE__
, line
)(info
->bmiHeader
.biWidth
== expected
->bmiHeader
.biWidth
,
1158 "Got unexpected bmiHeader.biWidth %ld, expected %ld.\n",
1159 info
->bmiHeader
.biWidth
, expected
->bmiHeader
.biWidth
);
1160 ok_(__FILE__
, line
)(info
->bmiHeader
.biHeight
== expected
->bmiHeader
.biHeight
,
1161 "Got unexpected bmiHeader.biHeight %ld, expected %ld.\n",
1162 info
->bmiHeader
.biHeight
, expected
->bmiHeader
.biHeight
);
1163 ok_(__FILE__
, line
)(info
->bmiHeader
.biPlanes
== expected
->bmiHeader
.biPlanes
,
1164 "Got unexpected bmiHeader.biPlanes %u, expected %u.\n",
1165 info
->bmiHeader
.biPlanes
, expected
->bmiHeader
.biPlanes
);
1166 ok_(__FILE__
, line
)(info
->bmiHeader
.biBitCount
== expected
->bmiHeader
.biBitCount
,
1167 "Got unexpected bmiHeader.biBitCount %u, expected %u.\n",
1168 info
->bmiHeader
.biBitCount
, expected
->bmiHeader
.biBitCount
);
1169 ok_(__FILE__
, line
)(info
->bmiHeader
.biCompression
== expected
->bmiHeader
.biCompression
,
1170 "Got unexpected bmiHeader.biCompression %#lx, expected %#lx.\n",
1171 info
->bmiHeader
.biCompression
, expected
->bmiHeader
.biCompression
);
1172 ok_(__FILE__
, line
)(info
->bmiHeader
.biSizeImage
== expected
->bmiHeader
.biSizeImage
,
1173 "Got unexpected bmiHeader.biSizeImage %lu, expected %lu.\n",
1174 info
->bmiHeader
.biSizeImage
, expected
->bmiHeader
.biSizeImage
);
1175 ok_(__FILE__
, line
)(info
->bmiHeader
.biXPelsPerMeter
== expected
->bmiHeader
.biXPelsPerMeter
,
1176 "Got unexpected bmiHeader.biXPelsPerMeter %ld, expected %ld.\n",
1177 info
->bmiHeader
.biXPelsPerMeter
, expected
->bmiHeader
.biXPelsPerMeter
);
1178 ok_(__FILE__
, line
)(info
->bmiHeader
.biYPelsPerMeter
== expected
->bmiHeader
.biYPelsPerMeter
,
1179 "Got unexpected bmiHeader.xxxxxx %ld, expected %ld.\n",
1180 info
->bmiHeader
.biYPelsPerMeter
, expected
->bmiHeader
.biYPelsPerMeter
);
1181 todo_wine_if(expected
->bmiHeader
.biClrUsed
!= 0)
1182 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrUsed
== expected
->bmiHeader
.biClrUsed
,
1183 "Got unexpected bmiHeader.biClrUsed %lu, expected %lu.\n",
1184 info
->bmiHeader
.biClrUsed
, expected
->bmiHeader
.biClrUsed
);
1185 todo_wine_if(expected
->bmiHeader
.biClrImportant
!= 0)
1186 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrImportant
== expected
->bmiHeader
.biClrImportant
,
1187 "Got unexpected bmiHeader.biClrImportant %lu, expected %lu.\n",
1188 info
->bmiHeader
.biClrImportant
, expected
->bmiHeader
.biClrImportant
);
1191 #define check_dmo_media_type(a, b) check_dmo_media_type_(__LINE__, a, b)
1192 static void check_dmo_media_type_(int line
, DMO_MEDIA_TYPE
*media_type
, const DMO_MEDIA_TYPE
*expected
)
1194 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->majortype
, &expected
->majortype
),
1195 "Got unexpected majortype %s, expected %s.\n",
1196 debugstr_guid(&media_type
->majortype
), debugstr_guid(&expected
->majortype
));
1197 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->subtype
, &expected
->subtype
),
1198 "Got unexpected subtype %s, expected %s.\n",
1199 debugstr_guid(&media_type
->subtype
), debugstr_guid(&expected
->subtype
));
1200 ok_(__FILE__
, line
)(media_type
->bFixedSizeSamples
== expected
->bFixedSizeSamples
,
1201 "Got unexpected bFixedSizeSamples %d, expected %d.\n",
1202 media_type
->bFixedSizeSamples
, expected
->bFixedSizeSamples
);
1203 ok_(__FILE__
, line
)(media_type
->bTemporalCompression
== expected
->bTemporalCompression
,
1204 "Got unexpected bTemporalCompression %d, expected %d.\n",
1205 media_type
->bTemporalCompression
, expected
->bTemporalCompression
);
1206 ok_(__FILE__
, line
)(media_type
->lSampleSize
== expected
->lSampleSize
,
1207 "Got unexpected lSampleSize %lu, expected %lu.\n",
1208 media_type
->lSampleSize
, expected
->lSampleSize
);
1209 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->formattype
, &expected
->formattype
),
1210 "Got unexpected formattype %s.\n",
1211 debugstr_guid(&media_type
->formattype
));
1212 ok_(__FILE__
, line
)(media_type
->pUnk
== NULL
, "Got unexpected pUnk %p.\n", media_type
->pUnk
);
1213 todo_wine_if(expected
->cbFormat
&& expected
->cbFormat
!= sizeof(VIDEOINFOHEADER
))
1214 ok_(__FILE__
, line
)(media_type
->cbFormat
== expected
->cbFormat
,
1215 "Got unexpected cbFormat %lu, expected %lu.\n",
1216 media_type
->cbFormat
, expected
->cbFormat
);
1218 if (expected
->pbFormat
)
1220 ok_(__FILE__
, line
)(!!media_type
->pbFormat
, "Got NULL pbFormat.\n");
1221 if (!media_type
->pbFormat
)
1224 if (IsEqualGUID(&media_type
->formattype
, &FORMAT_VideoInfo
)
1225 && IsEqualGUID(&expected
->formattype
, &FORMAT_VideoInfo
))
1226 check_video_info_header((VIDEOINFOHEADER
*)media_type
->pbFormat
, (VIDEOINFOHEADER
*)expected
->pbFormat
);
1230 static void check_dmo_get_input_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1232 DMO_MEDIA_TYPE media_type
;
1236 hr
= IMediaObject_GetInputType(media_object
, 1, 0, NULL
);
1237 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1238 hr
= IMediaObject_GetInputType(media_object
, 1, 0, &media_type
);
1239 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1240 hr
= IMediaObject_GetInputType(media_object
, 1, count
, &media_type
);
1241 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1242 hr
= IMediaObject_GetInputType(media_object
, 0, count
, &media_type
);
1243 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1244 hr
= IMediaObject_GetInputType(media_object
, 0, count
, NULL
);
1245 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1246 hr
= IMediaObject_GetInputType(media_object
, 0, 0xdeadbeef, NULL
);
1247 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1248 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, NULL
);
1249 ok(hr
== S_OK
, "GetInputType returned %#lx.\n", hr
);
1250 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, &media_type
);
1251 ok(hr
== S_OK
, "GetInputType returned %#lx.\n", hr
);
1253 MoFreeMediaType(&media_type
);
1256 while (SUCCEEDED(hr
= IMediaObject_GetInputType(media_object
, 0, ++i
, &media_type
)))
1258 winetest_push_context("in %lu", i
);
1259 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1260 MoFreeMediaType(&media_type
);
1261 winetest_pop_context();
1264 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1265 ok(i
== count
, "%lu types.\n", i
);
1268 static void check_dmo_get_output_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1270 DMO_MEDIA_TYPE media_type
;
1274 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, NULL
);
1275 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1276 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, &media_type
);
1277 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1278 hr
= IMediaObject_GetOutputType(media_object
, 1, count
, &media_type
);
1279 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1280 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, &media_type
);
1281 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned %#lx.\n", hr
);
1282 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, NULL
);
1283 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned %#lx.\n", hr
);
1284 hr
= IMediaObject_GetOutputType(media_object
, 0, 0xdeadbeef, NULL
);
1285 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned %#lx.\n", hr
);
1286 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, NULL
);
1287 ok(hr
== S_OK
, "GetOutputType returned %#lx.\n", hr
);
1288 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, &media_type
);
1289 ok(hr
== S_OK
, "GetOutputType returned %#lx.\n", hr
);
1291 MoFreeMediaType(&media_type
);
1294 while (SUCCEEDED(hr
= IMediaObject_GetOutputType(media_object
, 0, ++i
, &media_type
)))
1296 winetest_push_context("out %lu", i
);
1297 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1298 MoFreeMediaType(&media_type
);
1299 winetest_pop_context();
1302 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned %#lx.\n", hr
);
1303 ok(i
== count
, "%lu types.\n", i
);
1306 static void check_dmo_set_input_type(IMediaObject
*media_object
, const GUID
*subtype
)
1308 DMO_MEDIA_TYPE bad_media_type
, *good_media_type
;
1309 VIDEOINFOHEADER
*header
;
1314 const DWORD flags
[] = {0, 0x4, DMO_SET_TYPEF_CLEAR
, DMO_SET_TYPEF_TEST_ONLY
, DMO_SET_TYPEF_TEST_ONLY
| 0x4};
1316 memset(&bad_media_type
, 0, sizeof(bad_media_type
));
1317 good_media_type
= (DMO_MEDIA_TYPE
*)buffer
;
1318 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1319 header
= (VIDEOINFOHEADER
*)(good_media_type
+ 1);
1321 /* Test invalid stream index. */
1322 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1325 hr
= IMediaObject_SetInputType(media_object
, 1, NULL
, flag
);
1326 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1327 hr
= IMediaObject_SetInputType(media_object
, 1, &bad_media_type
, flag
);
1328 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1329 hr
= IMediaObject_SetInputType(media_object
, 1, good_media_type
, flag
);
1330 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1333 /* Test unaccepted type. */
1334 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1337 if (!(flag
& DMO_SET_TYPEF_CLEAR
))
1339 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, flag
);
1340 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1342 hr
= IMediaObject_SetInputType(media_object
, 0, &bad_media_type
, flag
);
1343 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1346 /* Test clearing the type. */
1347 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1349 flag
= DMO_SET_TYPEF_CLEAR
| flags
[i
];
1350 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, flag
);
1351 ok(hr
== S_OK
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1354 /* Test accepted type. */
1355 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1358 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, flag
);
1359 ok(hr
== S_OK
, "SetInputType returned %#lx for flag %#lx.", hr
, flag
);
1362 /* Test unconsidered header member.*/
1363 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1364 header
->dwBitRate
= 0xdeadbeef;
1365 header
->dwBitErrorRate
= 0xdeadbeef;
1366 header
->AvgTimePerFrame
= 0xdeadbeef;
1367 header
->bmiHeader
.biPlanes
= 0xdead;
1368 header
->bmiHeader
.biBitCount
= 0xdead;
1369 header
->bmiHeader
.biSizeImage
= 0xdeadbeef;
1370 header
->bmiHeader
.biXPelsPerMeter
= 0xdead;
1371 header
->bmiHeader
.biYPelsPerMeter
= 0xdead;
1372 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, 0);
1373 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1375 /* Test invalid major type. */
1376 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1377 good_media_type
->majortype
= MFMediaType_Default
;
1378 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1379 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1381 /* Test invalid subtype. */
1382 init_dmo_media_type_video(good_media_type
, &MEDIASUBTYPE_None
, 16, 16);
1383 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1384 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1386 /* Test invalid format type. */
1387 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1388 good_media_type
->formattype
= FORMAT_None
;
1389 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1390 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1392 /* Test invalid format size. */
1393 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1394 good_media_type
->cbFormat
= 1;
1395 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1396 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1398 /* Test NULL format pointer. */
1399 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1400 good_media_type
->pbFormat
= NULL
;
1401 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1402 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1404 /* Test video header struct size. */
1405 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1406 header
->bmiHeader
.biSize
= 0;
1407 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1409 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1410 header
->bmiHeader
.biSize
= 1;
1411 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1413 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1414 header
->bmiHeader
.biSize
= 0xdeadbeef;
1415 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1417 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1420 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1421 header
->bmiHeader
.biWidth
= 0;
1422 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1424 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1425 header
->bmiHeader
.biWidth
= -1;
1426 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1428 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1429 header
->bmiHeader
.biWidth
= 4096 + 1;
1430 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1432 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1433 header
->bmiHeader
.biWidth
= 4096;
1434 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1435 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1438 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1439 header
->bmiHeader
.biHeight
= 0;
1440 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1442 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1443 header
->bmiHeader
.biHeight
= 4096 + 1;
1444 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1446 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1447 header
->bmiHeader
.biHeight
= 4096;
1448 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1449 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1450 header
->bmiHeader
.biHeight
= -4096;
1451 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1452 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1454 /* Test compression. */
1455 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1456 header
->bmiHeader
.biCompression
= 0;
1457 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1459 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1460 header
->bmiHeader
.biCompression
= 1;
1461 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1462 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1463 header
->bmiHeader
.biCompression
= 2;
1464 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1465 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1466 header
->bmiHeader
.biCompression
= 0xdeadbeef;
1467 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1468 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1471 static void check_dmo_set_output_type(IMediaObject
*media_object
, const GUID
*subtype
)
1473 DMO_MEDIA_TYPE bad_media_type
, *good_media_type
;
1478 const DWORD flags
[] = {0, 0x4, DMO_SET_TYPEF_CLEAR
, DMO_SET_TYPEF_TEST_ONLY
, DMO_SET_TYPEF_TEST_ONLY
| 0x4};
1480 memset(&bad_media_type
, 0, sizeof(bad_media_type
));
1481 good_media_type
= (DMO_MEDIA_TYPE
*)buffer
;
1482 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1484 /* Test invalid stream index. */
1485 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1488 hr
= IMediaObject_SetOutputType(media_object
, 1, NULL
, flag
);
1489 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1490 hr
= IMediaObject_SetOutputType(media_object
, 1, &bad_media_type
, flag
);
1491 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1492 hr
= IMediaObject_SetOutputType(media_object
, 1, good_media_type
, flag
);
1493 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1496 /* Test unaccepted type. */
1497 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1500 if (!(flag
& DMO_SET_TYPEF_CLEAR
))
1502 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, flag
);
1503 ok(hr
== E_POINTER
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1505 hr
= IMediaObject_SetOutputType(media_object
, 0, &bad_media_type
, flag
);
1506 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1509 /* Test clearing the type. */
1510 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1512 flag
= DMO_SET_TYPEF_CLEAR
| flags
[i
];
1513 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, flag
);
1514 ok(hr
== S_OK
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1517 /* Test accepted type. */
1518 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1521 hr
= IMediaObject_SetOutputType(media_object
, 0, good_media_type
, flag
);
1522 ok(hr
== S_OK
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1527 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
1529 if (IsEqualIID(riid
, &IID_IUnknown
))
1532 IUnknown_AddRef(iface
);
1537 return E_NOINTERFACE
;
1540 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
1545 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
1550 static const IUnknownVtbl test_unk_vtbl
=
1552 test_unk_QueryInterface
,
1557 static BOOL
is_supported_video_type(const GUID
*guid
)
1559 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
1560 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
1561 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
1562 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
1563 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
1564 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
1565 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
1566 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
1567 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
1568 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
1569 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
1570 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
1571 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
1572 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
1573 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
1574 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
1575 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
1576 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
1577 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
1578 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
1579 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
1580 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
1581 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
1582 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
1583 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
1584 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
1585 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
1586 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
1587 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
1588 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
1589 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
1592 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
1598 hr
= IMFMediaType_GetMajorType(type
, &major
);
1599 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
1601 hr
= IMFMediaType_GetCount(type
, &count
);
1602 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
1603 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
1605 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
1608 static void test_sample_copier(void)
1610 static const struct attribute_desc expect_transform_attributes
[] =
1612 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, 1),
1615 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 16 * 16};
1616 const MFT_INPUT_STREAM_INFO initial_input_info
= {0}, input_info
= {.cbSize
= 16 * 16};
1617 IMFMediaType
*mediatype
, *mediatype2
;
1618 IMFSample
*sample
, *client_sample
;
1619 IMFMediaBuffer
*media_buffer
;
1620 MFT_INPUT_STREAM_INFO info
;
1621 DWORD flags
, output_status
;
1622 IMFTransform
*copier
;
1626 if (!pMFCreateSampleCopierMFT
)
1628 win_skip("MFCreateSampleCopierMFT() is not available.\n");
1632 winetest_push_context("copier");
1634 hr
= pMFCreateSampleCopierMFT(&copier
);
1635 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1637 check_interface(copier
, &IID_IMFTransform
, TRUE
);
1638 check_interface(copier
, &IID_IMediaObject
, FALSE
);
1639 check_interface(copier
, &IID_IPropertyStore
, FALSE
);
1640 check_interface(copier
, &IID_IPropertyBag
, FALSE
);
1642 check_mft_optional_methods(copier
, 1);
1643 check_mft_get_attributes(copier
, expect_transform_attributes
, FALSE
);
1645 /* Available types. */
1646 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
1647 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1648 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1649 IMFMediaType_Release(mediatype
);
1651 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
1652 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1653 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1654 IMFMediaType_Release(mediatype
);
1656 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
1657 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1659 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
1660 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1662 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
1663 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1665 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
1666 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1668 check_mft_get_input_current_type(copier
, NULL
);
1669 check_mft_get_output_current_type(copier
, NULL
);
1671 hr
= MFCreateSample(&sample
);
1672 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1674 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1675 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1677 hr
= MFCreateMediaType(&mediatype
);
1678 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1680 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1681 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
1683 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1684 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1686 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
1687 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1689 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1690 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1692 check_mft_get_input_stream_info(copier
, S_OK
, &initial_input_info
);
1693 check_mft_get_output_stream_info(copier
, S_OK
, &initial_output_info
);
1695 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1696 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1698 memset(&info
, 0xcd, sizeof(info
));
1699 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &info
);
1700 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
1701 check_member(info
, initial_input_info
, "%I64d", hnsMaxLatency
);
1702 check_member(info
, initial_input_info
, "%#lx", dwFlags
);
1704 check_member(info
, initial_input_info
, "%#lx", cbSize
);
1705 check_member(info
, initial_input_info
, "%#lx", cbMaxLookahead
);
1706 check_member(info
, initial_input_info
, "%#lx", cbAlignment
);
1707 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1709 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1710 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1711 IMFMediaType_Release(mediatype2
);
1713 check_mft_get_input_current_type(copier
, NULL
);
1715 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1716 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1718 /* Setting input type resets output type. */
1719 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1720 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1721 IMFMediaType_Release(mediatype2
);
1723 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1724 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1726 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1727 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1729 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
1730 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1731 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
1732 IMFMediaType_Release(mediatype2
);
1734 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1735 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1737 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
1738 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1739 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
1740 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1741 IMFMediaType_Release(mediatype2
);
1743 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1744 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1745 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
1747 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
1748 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1749 IMFMediaType_Release(mediatype2
);
1751 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1752 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1754 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1755 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
1757 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1758 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1759 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1761 /* Pushing samples. */
1762 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1763 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1765 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1766 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1767 IMFMediaBuffer_Release(media_buffer
);
1769 EXPECT_REF(sample
, 1);
1770 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1771 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1772 EXPECT_REF(sample
, 2);
1774 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1775 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1776 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1778 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1779 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1780 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
1782 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1783 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
1785 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1786 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1788 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1789 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1791 hr
= MFCreateSample(&client_sample
);
1792 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1794 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
1795 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1796 IMFMediaBuffer_Release(media_buffer
);
1798 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1799 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1800 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1801 EXPECT_REF(sample
, 1);
1803 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1804 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
1805 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1808 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1809 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1810 EXPECT_REF(sample
, 2);
1812 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
1813 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1815 ref
= IMFSample_Release(sample
);
1816 ok(ref
== 0, "Release returned %ld\n", ref
);
1817 ref
= IMFSample_Release(client_sample
);
1818 ok(ref
== 0, "Release returned %ld\n", ref
);
1820 ref
= IMFTransform_Release(copier
);
1821 ok(ref
== 0, "Release returned %ld\n", ref
);
1822 ref
= IMFMediaType_Release(mediatype
);
1823 ok(ref
== 0, "Release returned %ld\n", ref
);
1825 winetest_pop_context();
1828 struct sample_metadata
1835 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
1836 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
1838 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
1839 IMFSample
*input_sample
, *output_sample
;
1840 DWORD flags
, output_status
;
1845 hr
= MFCreateSample(&input_sample
);
1846 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1850 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
1851 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1853 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
1854 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1856 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
1857 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1860 hr
= MFCreateSample(&output_sample
);
1861 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1863 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
1864 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1866 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
1867 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1869 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
1870 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1872 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
1873 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1875 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
1876 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1878 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
1879 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1881 hr
= check_mft_process_output(copier
, output_sample
, &output_status
);
1882 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1883 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1885 if (!md
) md
= &zero_md
;
1887 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
1888 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1889 ok(md
->flags
== flags
, "Unexpected flags.\n");
1890 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
1891 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1892 ok(md
->time
== time
, "Unexpected time.\n");
1893 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
1894 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1895 ok(md
->duration
== time
, "Unexpected duration.\n");
1897 ref
= IMFSample_Release(input_sample
);
1898 ok(ref
== 0, "Release returned %ld\n", ref
);
1899 ref
= IMFSample_Release(output_sample
);
1900 ok(ref
== 0, "Release returned %ld\n", ref
);
1903 static void test_sample_copier_output_processing(void)
1905 IMFMediaBuffer
*input_buffer
, *output_buffer
;
1906 MFT_OUTPUT_STREAM_INFO output_info
;
1907 struct sample_metadata md
;
1908 IMFMediaType
*mediatype
;
1909 IMFTransform
*copier
;
1915 if (!pMFCreateSampleCopierMFT
)
1918 hr
= pMFCreateSampleCopierMFT(&copier
);
1919 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1921 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
1922 hr
= MFCreateMediaType(&mediatype
);
1923 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1925 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1926 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1928 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
1929 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1931 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1932 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1934 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1935 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1937 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1938 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1940 /* Source and destination are linear buffers, destination is twice as large. */
1941 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
1942 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
1944 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
1945 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1947 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1948 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1949 memset(ptr
, 0xcc, max_length
);
1950 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1951 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1953 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
1954 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1956 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
1957 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1958 memset(ptr
, 0xaa, max_length
);
1959 hr
= IMFMediaBuffer_Unlock(input_buffer
);
1960 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1961 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
1962 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1964 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
1966 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
1967 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1968 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
1970 hr
= IMFMediaBuffer_Unlock(output_buffer
);
1971 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1976 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
1978 ref
= IMFMediaBuffer_Release(input_buffer
);
1979 ok(ref
== 0, "Release returned %ld\n", ref
);
1980 ref
= IMFMediaBuffer_Release(output_buffer
);
1981 ok(ref
== 0, "Release returned %ld\n", ref
);
1983 ref
= IMFTransform_Release(copier
);
1984 ok(ref
== 0, "Release returned %ld\n", ref
);
1985 ref
= IMFMediaType_Release(mediatype
);
1986 ok(ref
== 0, "Release returned %ld\n", ref
);
1989 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
1991 IMFMediaBuffer
*media_buffer
;
1998 hr
= MFCreateSample(&sample
);
1999 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
2000 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
2001 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
2002 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
2003 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
2004 ok(length
== 0, "got length %lu\n", length
);
2005 if (!data
) memset(buffer
, 0xcd, size
);
2006 else memcpy(buffer
, data
, size
);
2007 hr
= IMFMediaBuffer_Unlock(media_buffer
);
2008 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
2009 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
2010 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
2011 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
2012 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
2013 ret
= IMFMediaBuffer_Release(media_buffer
);
2014 ok(ret
== 1, "Release returned %lu\n", ret
);
2019 static const BYTE aac_codec_data
[14] = {0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x08};
2021 static void test_aac_encoder(void)
2023 const GUID
*const class_id
= &CLSID_AACMFTEncoder
;
2024 const struct transform_info expect_mft_info
=
2026 .name
= L
"Microsoft AAC Audio Encoder MFT",
2027 .major_type
= &MFMediaType_Audio
,
2030 {.subtype
= &MFAudioFormat_PCM
},
2034 {.subtype
= &MFAudioFormat_AAC
},
2038 static 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_PCM
, .required
= TRUE
),
2042 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2043 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2044 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2047 const struct attribute_desc output_type_desc
[] =
2049 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2050 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
2051 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2052 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2053 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2054 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000, .required
= TRUE
),
2058 static const struct attribute_desc expect_input_type_desc
[] =
2060 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
2061 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2062 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2063 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2064 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2065 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
2066 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2067 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 2),
2068 ATTR_UINT32(MF_MT_AVG_BITRATE
, 44100 * 2 * 8),
2069 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
2070 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2071 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2072 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2075 const struct attribute_desc expect_output_type_desc
[] =
2077 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
2078 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2079 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2080 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2081 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2082 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2083 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2084 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
2085 ATTR_UINT32(MF_MT_AVG_BITRATE
, 96000),
2086 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
2087 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
2088 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2089 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
2090 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2091 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
)),
2094 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 0x600};
2095 const MFT_INPUT_STREAM_INFO input_info
= {0};
2097 const struct buffer_desc output_buffer_desc
[] =
2099 {.length
= -1 /* variable */},
2101 const struct attribute_desc output_sample_attributes
[] =
2103 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2106 const struct sample_desc output_sample_desc
[] =
2110 .attributes
= output_sample_attributes
,
2111 .sample_time
= 0, .sample_duration
= 113823,
2112 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2116 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
2117 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
2118 IMFSample
*input_sample
, *output_sample
;
2119 IMFCollection
*output_samples
;
2120 ULONG i
, ret
, audio_data_len
;
2121 DWORD length
, output_status
;
2122 IMFTransform
*transform
;
2123 const BYTE
*audio_data
;
2127 hr
= CoInitialize(NULL
);
2128 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2130 winetest_push_context("aacenc");
2132 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2134 check_mft_get_info(class_id
, &expect_mft_info
);
2136 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2137 &IID_IMFTransform
, (void **)&transform
)))
2140 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2141 check_interface(transform
, &IID_IMediaObject
, FALSE
);
2142 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
2143 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
2145 check_mft_optional_methods(transform
, 1);
2146 check_mft_get_attributes(transform
, NULL
, FALSE
);
2147 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2148 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
2150 check_mft_set_output_type_required(transform
, output_type_desc
);
2151 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2152 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2154 check_mft_set_input_type_required(transform
, input_type_desc
);
2155 check_mft_set_input_type(transform
, input_type_desc
);
2156 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2158 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2159 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2161 if (!has_video_processor
)
2163 win_skip("Skipping AAC encoder tests on Win7\n");
2167 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2168 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2170 input_sample
= create_sample(audio_data
, audio_data_len
);
2171 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2172 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2173 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2174 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2175 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2176 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2177 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2178 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2179 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2180 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2181 ref
= IMFSample_Release(input_sample
);
2182 ok(ref
<= 1, "Release returned %ld\n", ref
);
2184 hr
= MFCreateCollection(&output_samples
);
2185 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2187 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2188 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2190 winetest_push_context("%lu", i
);
2191 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2192 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2193 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2194 ref
= IMFSample_Release(output_sample
);
2195 ok(ref
== 1, "Release returned %ld\n", ref
);
2196 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2197 winetest_pop_context();
2199 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2200 ret
= IMFSample_Release(output_sample
);
2201 ok(ret
== 0, "Release returned %lu\n", ret
);
2202 ok(i
== 88, "got %lu output samples\n", i
);
2204 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacencdata.bin");
2205 ok(ret
== 0, "got %lu%% diff\n", ret
);
2206 IMFCollection_Release(output_samples
);
2208 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2209 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2210 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2211 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2212 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2213 ok(length
== 0, "got length %lu\n", length
);
2214 ret
= IMFSample_Release(output_sample
);
2215 ok(ret
== 0, "Release returned %lu\n", ret
);
2218 ret
= IMFTransform_Release(transform
);
2219 ok(ret
== 0, "Release returned %lu\n", ret
);
2222 winetest_pop_context();
2226 static void test_aac_decoder(void)
2228 const GUID
*const class_id
= &CLSID_MSAACDecMFT
;
2229 const struct transform_info expect_mft_info
=
2231 .name
= L
"Microsoft AAC Audio Decoder MFT",
2232 .major_type
= &MFMediaType_Audio
,
2235 {.subtype
= &MFAudioFormat_AAC
},
2236 {.subtype
= &MFAudioFormat_RAW_AAC1
},
2237 {.subtype
= &MFAudioFormat_ADTS
, .broken
= TRUE
/* <= w8 */},
2241 {.subtype
= &MFAudioFormat_Float
},
2242 {.subtype
= &MFAudioFormat_PCM
},
2246 static const struct attribute_desc expect_input_attributes
[] =
2248 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2249 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2250 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2251 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 6),
2252 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 24),
2253 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
2254 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 1152000),
2257 static const media_type_desc expect_available_inputs
[] =
2260 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2261 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2262 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2263 /* MF_MT_USER_DATA with some AAC codec data */
2266 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_RAW_AAC1
),
2269 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2270 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2271 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 1),
2272 /* MF_MT_USER_DATA with some AAC codec data */
2275 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2276 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2277 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 3),
2278 /* MF_MT_USER_DATA with some AAC codec data */
2281 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_ADTS
),
2284 static const struct attribute_desc expect_output_attributes
[] =
2286 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2287 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2288 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2289 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2290 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2293 static const media_type_desc expect_available_outputs
[] =
2296 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2297 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2298 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2299 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2300 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4 * 44100),
2303 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2304 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2305 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2306 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
2307 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * 44100),
2310 const struct attribute_desc expect_transform_attributes
[] =
2312 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, !has_video_processor
/* 1 on W7 */, .todo
= TRUE
),
2313 /* more AAC decoder specific attributes from CODECAPI */
2316 const struct attribute_desc input_type_desc
[] =
2318 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2319 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
2320 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2321 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
), .required
= TRUE
),
2322 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2323 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2324 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
2325 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
2326 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2329 static const struct attribute_desc output_type_desc
[] =
2331 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2332 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2333 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2334 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2335 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2338 const MFT_OUTPUT_STREAM_INFO output_info
=
2340 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
,
2343 const MFT_INPUT_STREAM_INFO input_info
=
2345 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
2346 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_INPUT_STREAM_HOLDS_BUFFERS
,
2349 const struct buffer_desc output_buffer_desc
[] =
2353 const struct attribute_desc output_sample_attributes
[] =
2355 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2358 const struct sample_desc output_sample_desc
[] =
2361 .attributes
= output_sample_attributes
+ (has_video_processor
? 0 : 1) /* MFSampleExtension_CleanPoint missing on Win7 */,
2362 .sample_time
= 0, .sample_duration
= 232200,
2363 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2367 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2368 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
2369 IMFSample
*input_sample
, *output_sample
;
2370 ULONG i
, ret
, ref
, aacenc_data_len
;
2371 IMFCollection
*output_samples
;
2372 DWORD length
, output_status
;
2373 IMFMediaType
*media_type
;
2374 IMFTransform
*transform
;
2375 const BYTE
*aacenc_data
;
2378 hr
= CoInitialize(NULL
);
2379 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2381 winetest_push_context("aacdec");
2383 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2385 check_mft_get_info(class_id
, &expect_mft_info
);
2387 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2388 &IID_IMFTransform
, (void **)&transform
)))
2391 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2392 check_interface(transform
, &IID_IMediaObject
, FALSE
);
2393 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
2394 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
2396 check_mft_optional_methods(transform
, 1);
2397 check_mft_get_attributes(transform
, expect_transform_attributes
, FALSE
);
2398 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2399 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2401 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2402 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2405 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2407 winetest_push_context("in %lu", i
);
2408 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2409 check_media_type(media_type
, expect_input_attributes
, -1);
2410 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2411 ret
= IMFMediaType_Release(media_type
);
2412 ok(ret
<= 1, "Release returned %lu\n", ret
);
2413 winetest_pop_context();
2415 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
2416 ok(i
== ARRAY_SIZE(expect_available_inputs
)
2417 || broken(i
== 2) /* w7 */ || broken(i
== 4) /* w8 */,
2418 "%lu input media types\n", i
);
2420 /* setting output media type first doesn't work */
2421 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
2422 check_mft_get_output_current_type(transform
, NULL
);
2424 check_mft_set_input_type_required(transform
, input_type_desc
);
2425 check_mft_set_input_type(transform
, input_type_desc
);
2426 check_mft_get_input_current_type(transform
, input_type_desc
);
2428 /* check new output media types */
2431 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
2433 winetest_push_context("out %lu", i
);
2434 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
2435 check_media_type(media_type
, expect_output_attributes
, -1);
2436 check_media_type(media_type
, expect_available_outputs
[i
], -1);
2437 ret
= IMFMediaType_Release(media_type
);
2438 ok(ret
<= 1, "Release returned %lu\n", ret
);
2439 winetest_pop_context();
2441 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
2442 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
2444 check_mft_set_output_type_required(transform
, output_type_desc
);
2445 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2446 check_mft_get_output_current_type(transform
, output_type_desc
);
2448 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2449 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2451 load_resource(L
"aacencdata.bin", &aacenc_data
, &aacenc_data_len
);
2452 ok(aacenc_data_len
== 24861, "got length %lu\n", aacenc_data_len
);
2454 input_sample
= create_sample(aacenc_data
+ sizeof(DWORD
), *(DWORD
*)aacenc_data
);
2455 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2456 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2457 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2458 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2460 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2461 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2463 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2464 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
2465 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2466 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2467 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2469 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2470 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2471 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2472 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2474 hr
= MFCreateCollection(&output_samples
);
2475 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2477 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2478 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2480 winetest_push_context("%lu", i
);
2481 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2482 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2483 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2484 ref
= IMFSample_Release(output_sample
);
2485 ok(ref
== 1, "Release returned %ld\n", ref
);
2486 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2487 winetest_pop_context();
2489 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2490 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2491 ret
= IMFSample_Release(output_sample
);
2492 ok(ret
== 0, "Release returned %lu\n", ret
);
2493 ok(i
== 1, "got %lu output samples\n", i
);
2495 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacdecdata.bin");
2496 todo_wine_if(ret
<= 5)
2497 ok(ret
== 0, "got %lu%% diff\n", ret
);
2498 IMFCollection_Release(output_samples
);
2500 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2501 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2502 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2503 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2504 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2505 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2506 ok(length
== 0, "got length %lu\n", length
);
2507 ret
= IMFSample_Release(output_sample
);
2508 ok(ret
== 0, "Release returned %lu\n", ret
);
2510 ret
= IMFSample_Release(input_sample
);
2511 ok(ret
== 0, "Release returned %lu\n", ret
);
2512 ret
= IMFTransform_Release(transform
);
2513 ok(ret
== 0, "Release returned %lu\n", ret
);
2516 winetest_pop_context();
2520 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
2521 static const ULONG wmaenc_block_size
= 1487;
2522 static const ULONG wmadec_block_size
= 0x2000;
2524 static void test_wma_encoder(void)
2526 const GUID
*const class_id
= &CLSID_CWMAEncMediaObject
;
2527 const struct transform_info expect_mft_info
=
2529 .name
= L
"WMAudio Encoder MFT",
2530 .major_type
= &MFMediaType_Audio
,
2533 {.subtype
= &MFAudioFormat_PCM
},
2534 {.subtype
= &MFAudioFormat_Float
},
2538 {.subtype
= &MFAudioFormat_WMAudioV8
},
2539 {.subtype
= &MFAudioFormat_WMAudioV9
},
2540 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2543 const struct transform_info expect_dmo_info
=
2545 .name
= L
"WMAudio Encoder DMO",
2546 .major_type
= &MEDIATYPE_Audio
,
2549 {.subtype
= &MEDIASUBTYPE_PCM
},
2553 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2554 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2555 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2559 static const struct attribute_desc input_type_desc
[] =
2561 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2562 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
2563 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2564 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
2565 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2566 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
2567 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
2570 const struct attribute_desc output_type_desc
[] =
2572 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2573 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2574 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2575 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2576 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003, .required
= TRUE
),
2577 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2578 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2581 static const struct attribute_desc expect_input_type_desc
[] =
2583 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2584 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2585 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2586 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2587 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2588 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2589 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
2590 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
2591 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2594 const struct attribute_desc expect_output_type_desc
[] =
2596 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2597 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2598 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2599 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2600 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2601 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2602 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2603 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2606 const MFT_OUTPUT_STREAM_INFO output_info
=
2608 .cbSize
= wmaenc_block_size
,
2611 const MFT_INPUT_STREAM_INFO input_info
=
2613 .hnsMaxLatency
= 19969161,
2618 const struct buffer_desc output_buffer_desc
[] =
2620 {.length
= wmaenc_block_size
},
2622 const struct attribute_desc output_sample_attributes
[] =
2624 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2625 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2628 const struct sample_desc output_sample_desc
[] =
2631 .attributes
= output_sample_attributes
,
2632 .sample_time
= 0, .sample_duration
= 3250794,
2633 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2636 .attributes
= output_sample_attributes
,
2637 .sample_time
= 3250794, .sample_duration
= 3715193,
2638 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2641 .attributes
= output_sample_attributes
,
2642 .sample_time
= 6965986, .sample_duration
= 3366893,
2643 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2647 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2648 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2649 IMFSample
*input_sample
, *output_sample
;
2650 IMFCollection
*output_samples
;
2651 DWORD length
, output_status
;
2652 IMFMediaType
*media_type
;
2653 IMFTransform
*transform
;
2654 const BYTE
*audio_data
;
2655 ULONG audio_data_len
;
2660 hr
= CoInitialize(NULL
);
2661 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2663 winetest_push_context("wmaenc");
2665 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2667 check_mft_get_info(class_id
, &expect_mft_info
);
2668 check_dmo_get_info(class_id
, &expect_dmo_info
);
2670 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2671 &IID_IMFTransform
, (void **)&transform
)))
2674 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2675 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2676 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2677 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2679 check_mft_optional_methods(transform
, 1);
2680 check_mft_get_attributes(transform
, NULL
, FALSE
);
2681 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2682 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2684 check_mft_set_input_type_required(transform
, input_type_desc
);
2686 hr
= MFCreateMediaType(&media_type
);
2687 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
2688 init_media_type(media_type
, input_type_desc
, -1);
2689 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
2690 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
2691 ret
= IMFMediaType_Release(media_type
);
2692 ok(ret
== 0, "Release returned %lu\n", ret
);
2694 check_mft_set_output_type_required(transform
, output_type_desc
);
2695 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2696 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2698 check_mft_set_input_type_required(transform
, input_type_desc
);
2699 check_mft_set_input_type(transform
, input_type_desc
);
2700 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2702 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2703 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2705 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2706 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2708 input_sample
= create_sample(audio_data
, audio_data_len
);
2709 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2710 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2711 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2712 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2713 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2714 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2715 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2716 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2717 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2718 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2719 ref
= IMFSample_Release(input_sample
);
2720 ok(ref
<= 1, "Release returned %ld\n", ref
);
2722 hr
= MFCreateCollection(&output_samples
);
2723 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2725 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2726 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2728 winetest_push_context("%lu", i
);
2729 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2730 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
2731 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2732 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2733 ref
= IMFSample_Release(output_sample
);
2734 ok(ref
== 1, "Release returned %ld\n", ref
);
2735 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2736 winetest_pop_context();
2738 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2739 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2740 ret
= IMFSample_Release(output_sample
);
2741 ok(ret
== 0, "Release returned %lu\n", ret
);
2742 ok(i
== 3, "got %lu output samples\n", i
);
2744 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmaencdata.bin");
2745 ok(ret
== 0, "got %lu%% diff\n", ret
);
2746 IMFCollection_Release(output_samples
);
2748 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2749 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2750 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2751 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2752 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2753 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2754 ok(length
== 0, "got length %lu\n", length
);
2755 ret
= IMFSample_Release(output_sample
);
2756 ok(ret
== 0, "Release returned %lu\n", ret
);
2758 ret
= IMFTransform_Release(transform
);
2759 ok(ret
== 0, "Release returned %lu\n", ret
);
2762 winetest_pop_context();
2766 static void test_wma_decoder(void)
2768 const GUID
*const class_id
= &CLSID_CWMADecMediaObject
;
2769 const struct transform_info expect_mft_info
=
2771 .name
= L
"WMAudio Decoder MFT",
2772 .major_type
= &MFMediaType_Audio
,
2775 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2776 {.subtype
= &MFAudioFormat_WMAudioV8
},
2777 {.subtype
= &MFAudioFormat_WMAudioV9
},
2778 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2782 {.subtype
= &MFAudioFormat_PCM
},
2783 {.subtype
= &MFAudioFormat_Float
},
2786 const struct transform_info expect_dmo_info
=
2788 .name
= L
"WMAudio Decoder DMO",
2789 .major_type
= &MEDIATYPE_Audio
,
2792 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2793 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2794 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2795 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2799 {.subtype
= &MEDIASUBTYPE_PCM
},
2800 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
2804 static const media_type_desc expect_available_inputs
[] =
2807 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2808 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
2809 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2812 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2813 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2814 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2817 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2818 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
2819 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2822 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2823 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
2824 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2827 static const media_type_desc expect_available_outputs
[] =
2830 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2831 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2832 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2833 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2834 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2835 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
2836 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2837 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2838 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2839 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2842 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2843 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2844 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2845 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2846 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2847 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
2848 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2849 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2850 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2851 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2855 const struct attribute_desc input_type_desc
[] =
2857 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2858 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2859 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2860 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2861 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2862 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2863 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003), /* not required by SetInputType, but needed for the transform to work */
2866 static const struct attribute_desc output_type_desc
[] =
2868 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2869 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2870 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2871 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2872 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2873 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
2874 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
2877 const struct attribute_desc expect_input_type_desc
[] =
2879 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2880 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2881 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2882 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2883 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2884 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2885 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2886 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2889 static const struct attribute_desc expect_output_type_desc
[] =
2891 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2892 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2893 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
2894 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2895 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2896 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2897 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2898 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2899 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2902 const MFT_INPUT_STREAM_INFO input_info
=
2904 .cbSize
= wmaenc_block_size
,
2907 const MFT_OUTPUT_STREAM_INFO output_info
=
2909 .cbSize
= wmadec_block_size
,
2913 const struct buffer_desc output_buffer_desc
[] =
2915 {.length
= wmadec_block_size
, .compare
= compare_pcm16
},
2916 {.length
= wmadec_block_size
/ 2, .compare
= compare_pcm16
, .todo_length
= TRUE
},
2918 const struct attribute_desc output_sample_attributes
[] =
2920 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2921 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2924 const struct attribute_desc output_sample_attributes_todo
[] =
2926 ATTR_UINT32(mft_output_sample_incomplete
, 1, .todo
= TRUE
),
2927 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2930 struct sample_desc output_sample_desc
[] =
2933 .attributes
= output_sample_attributes
+ 0,
2934 .sample_time
= 0, .sample_duration
= 928798,
2935 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 1,
2938 .attributes
= output_sample_attributes
+ 0,
2939 .sample_time
= 1857596, .sample_duration
= 928798,
2940 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
2943 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
2944 .sample_time
= 2786394, .sample_duration
= 464399,
2945 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
2949 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2950 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2951 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
2952 IMFSample
*input_sample
, *output_sample
;
2953 IMFCollection
*output_samples
;
2954 DWORD length
, output_status
;
2955 IMediaObject
*media_object
;
2956 IPropertyBag
*property_bag
;
2957 IMFMediaType
*media_type
;
2958 IMFTransform
*transform
;
2959 const BYTE
*wmaenc_data
;
2960 ULONG wmaenc_data_len
;
2964 hr
= CoInitialize(NULL
);
2965 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2967 winetest_push_context("wmadec");
2969 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2971 check_mft_get_info(class_id
, &expect_mft_info
);
2972 check_dmo_get_info(class_id
, &expect_dmo_info
);
2974 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2975 &IID_IMFTransform
, (void **)&transform
)))
2978 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2979 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2981 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2982 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2984 check_mft_optional_methods(transform
, 1);
2985 check_mft_get_attributes(transform
, NULL
, FALSE
);
2986 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2987 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2989 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2990 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2993 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2995 winetest_push_context("in %lu", i
);
2996 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2997 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2998 ret
= IMFMediaType_Release(media_type
);
2999 ok(ret
== 0, "Release returned %lu\n", ret
);
3000 winetest_pop_context();
3003 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3005 ok(i
== 4, "%lu input media types\n", i
);
3007 /* setting output media type first doesn't work */
3008 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3009 check_mft_get_output_current_type_(transform
, NULL
, TRUE
, FALSE
);
3011 check_mft_set_input_type_required(transform
, input_type_desc
);
3012 check_mft_set_input_type(transform
, input_type_desc
);
3013 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3015 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3016 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3018 /* check new output media types */
3021 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3023 winetest_push_context("out %lu", i
);
3024 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3025 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3026 ret
= IMFMediaType_Release(media_type
);
3027 ok(ret
== 0, "Release returned %lu\n", ret
);
3028 winetest_pop_context();
3030 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3031 ok(i
== 2, "%lu output media types\n", i
);
3033 check_mft_set_output_type_required(transform
, output_type_desc
);
3034 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3035 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, TRUE
, FALSE
);
3037 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3038 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3040 load_resource(L
"wmaencdata.bin", &wmaenc_data
, &wmaenc_data_len
);
3041 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
3043 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
3044 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3045 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3046 ret
= IMFSample_Release(input_sample
);
3047 ok(ret
== 0, "Release returned %lu\n", ret
);
3048 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
3049 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3050 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3051 ret
= IMFSample_Release(input_sample
);
3052 ok(ret
== 0, "Release returned %lu\n", ret
);
3053 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3054 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3055 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3056 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3057 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3058 ret
= IMFSample_Release(input_sample
);
3059 ok(ret
== 1, "Release returned %lu\n", ret
);
3061 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3062 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
3064 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3065 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3066 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
3067 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
3068 "got output[0].dwStatus %#lx\n", output_status
);
3070 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3071 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3072 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3073 ret
= IMFSample_Release(input_sample
);
3074 ok(ret
== 0, "Release returned %lu\n", ret
);
3076 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3077 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3078 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
3079 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
3080 "got output[0].dwStatus %#lx\n", output_status
);
3082 hr
= MFCreateCollection(&output_samples
);
3083 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3085 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3086 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
3088 winetest_push_context("%lu", i
);
3089 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
3090 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3091 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3092 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3093 ref
= IMFSample_Release(output_sample
);
3094 ok(ref
== 1, "Release returned %ld\n", ref
);
3095 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3096 winetest_pop_context();
3098 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3099 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3100 ret
= IMFSample_Release(output_sample
);
3101 ok(ret
== 0, "Release returned %lu\n", ret
);
3102 todo_wine_if(i
== 3) /* wmadec output depends on ffmpeg version used */
3103 ok(i
== 4, "got %lu output samples\n", i
);
3105 if (!strcmp(winetest_platform
, "wine") && i
== 3)
3106 output_sample_desc
[1].attributes
= output_sample_attributes_todo
;
3108 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmadecdata.bin");
3109 todo_wine_if(ret
> 0 && ret
<= 10) /* ffmpeg sometimes offsets the decoded data */
3110 ok(ret
== 0, "got %lu%% diff\n", ret
);
3111 IMFCollection_Release(output_samples
);
3113 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3114 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3115 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3116 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3117 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3118 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3119 ok(length
== 0, "got length %lu\n", length
);
3120 ret
= IMFSample_Release(output_sample
);
3121 ok(ret
== 0, "Release returned %lu\n", ret
);
3123 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3124 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3125 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3127 ret
= IMFTransform_Release(transform
);
3128 ok(ret
== 0, "Release returned %lu\n", ret
);
3129 ret
= IMFSample_Release(input_sample
);
3130 ok(ret
== 0, "Release returned %lu\n", ret
);
3132 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
3133 (void **)&unknown
);
3134 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
3135 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
3136 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3137 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
3138 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3139 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
3140 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3141 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
3142 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3144 ok( unknown
!= &outer
, "got outer IUnknown\n" );
3145 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
3146 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
3147 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
3148 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
3150 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
3151 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
3152 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
3153 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
3154 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
3155 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
3157 ref
= IUnknown_Release( tmp_unknown
);
3158 ok( ref
== 1, "Release returned %lu\n", ref
);
3159 ref
= IPropertyBag_Release( property_bag
);
3160 ok( ref
== 1, "Release returned %lu\n", ref
);
3161 ref
= IMediaObject_Release( media_object
);
3162 ok( ref
== 1, "Release returned %lu\n", ref
);
3163 ref
= IMFTransform_Release( transform
);
3164 ok( ref
== 1, "Release returned %lu\n", ref
);
3165 ref
= IUnknown_Release( unknown
);
3166 ok( ref
== 0, "Release returned %lu\n", ref
);
3169 winetest_pop_context();
3173 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
3174 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
3176 const BYTE
*sample_data
;
3178 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
3179 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
3180 sample_data
= *h264_buf
;
3185 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
3191 return create_sample(sample_data
, *h264_buf
- sample_data
);
3194 static void test_h264_decoder(void)
3196 const GUID
*const class_id
= &CLSID_MSH264DecoderMFT
;
3197 const struct transform_info expect_mft_info
=
3199 .name
= L
"Microsoft H264 Video Decoder MFT",
3200 .major_type
= &MFMediaType_Video
,
3203 {.subtype
= &MFVideoFormat_H264
},
3204 {.subtype
= &MFVideoFormat_H264_ES
},
3208 {.subtype
= &MFVideoFormat_NV12
},
3209 {.subtype
= &MFVideoFormat_YV12
},
3210 {.subtype
= &MFVideoFormat_IYUV
},
3211 {.subtype
= &MFVideoFormat_I420
},
3212 {.subtype
= &MFVideoFormat_YUY2
},
3215 static const media_type_desc default_inputs
[] =
3218 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3219 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
3222 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3223 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
3226 static const struct attribute_desc expect_transform_attributes
[] =
3228 ATTR_UINT32(MF_LOW_LATENCY
, 0),
3229 ATTR_UINT32(MF_SA_D3D_AWARE
, 1, .todo
= TRUE
),
3230 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1, .todo
= TRUE
),
3231 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0, .todo
= TRUE
),
3232 /* more H264 decoder specific attributes from CODECAPI */
3235 static const DWORD input_width
= 120, input_height
= 248;
3236 const media_type_desc default_outputs
[] =
3239 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3240 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3241 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3242 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3243 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3244 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3245 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3246 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3247 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3248 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3249 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3252 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3253 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3254 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3255 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3256 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3257 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3258 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3259 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3260 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3261 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3262 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3265 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3266 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3267 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3268 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3269 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3270 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3271 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3272 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3273 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3274 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3275 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3278 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3279 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3280 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3281 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3282 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3283 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3284 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3285 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3286 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3287 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3288 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3291 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3292 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3293 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3294 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3295 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
* 2),
3296 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3297 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3298 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3299 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3300 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 2),
3301 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3304 const struct attribute_desc input_type_desc
[] =
3306 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3307 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
, .required
= TRUE
),
3308 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3311 const struct attribute_desc output_type_desc
[] =
3313 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3314 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
3315 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
, .required
= TRUE
),
3316 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3317 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3318 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3319 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3320 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3323 const struct attribute_desc expect_input_type_desc
[] =
3325 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3326 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
3327 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3328 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 0),
3329 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 0),
3330 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
3331 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3332 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
3335 const struct attribute_desc expect_output_type_desc
[] =
3337 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3338 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3339 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3340 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3341 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3342 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3343 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3344 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3345 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3346 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3349 static const struct attribute_desc new_output_type_desc
[] =
3351 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3352 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3353 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3354 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3355 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3358 static const struct attribute_desc expect_new_output_type_desc
[] =
3360 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3361 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3362 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3363 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3364 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3365 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3366 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3369 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
3370 static const DWORD actual_width
= 96, actual_height
= 96;
3371 const media_type_desc actual_outputs
[] =
3374 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3375 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3376 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3377 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3378 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3379 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3380 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3381 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3382 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3383 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3384 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3385 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3388 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3389 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3390 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3391 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3392 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3393 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3394 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3395 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3396 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3397 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3398 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3399 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3402 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3403 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3404 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3405 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3406 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3407 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3408 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3409 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3410 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3411 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3412 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3413 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3416 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3417 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3418 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3419 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3420 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3421 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3422 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3423 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3424 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3425 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3426 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3427 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3430 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3431 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3432 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3433 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3434 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3435 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3436 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3437 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3438 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3439 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3440 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3441 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3444 const MFT_OUTPUT_STREAM_INFO initial_output_info
=
3446 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3447 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3448 .cbSize
= 1920 * 1088 * 2,
3450 const MFT_OUTPUT_STREAM_INFO output_info
=
3452 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3453 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3454 .cbSize
= input_width
* input_height
* 2,
3456 const MFT_OUTPUT_STREAM_INFO actual_output_info
=
3458 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3459 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3460 .cbSize
= actual_width
* actual_height
* 2,
3462 const MFT_INPUT_STREAM_INFO input_info
=
3464 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3465 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
,
3469 const struct attribute_desc output_sample_attributes
[] =
3471 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3474 const struct buffer_desc output_buffer_desc_nv12
=
3476 .length
= actual_width
* actual_height
* 3 / 2,
3477 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
3479 const struct sample_desc output_sample_desc_nv12
=
3481 .attributes
= output_sample_attributes
,
3482 .sample_time
= 0, .sample_duration
= 333667,
3483 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
3485 const struct buffer_desc output_buffer_desc_i420
=
3487 .length
= actual_width
* actual_height
* 3 / 2,
3488 .compare
= compare_i420
, .dump
= dump_i420
, .rect
= {.right
= 82, .bottom
= 84},
3490 const struct sample_desc expect_output_sample_i420
=
3492 .attributes
= output_sample_attributes
,
3493 .sample_time
= 333667, .sample_duration
= 333667, .todo_time
= 1334666 /* with VA-API */,
3494 .buffer_count
= 1, .buffers
= &output_buffer_desc_i420
,
3497 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
3498 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3499 IMFSample
*input_sample
, *output_sample
;
3500 const BYTE
*h264_encoded_data
;
3501 IMFCollection
*output_samples
;
3502 ULONG h264_encoded_data_len
;
3503 DWORD length
, output_status
;
3504 IMFAttributes
*attributes
;
3505 IMFMediaType
*media_type
;
3506 IMFTransform
*transform
;
3510 hr
= CoInitialize(NULL
);
3511 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3513 winetest_push_context("h264dec");
3515 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
3517 check_mft_get_info(class_id
, &expect_mft_info
);
3519 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3520 &IID_IMFTransform
, (void **)&transform
)))
3523 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3524 check_interface(transform
, &IID_IMediaObject
, FALSE
);
3525 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
3526 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
3528 check_mft_optional_methods(transform
, 1);
3529 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
3530 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3531 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
3533 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3534 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
3535 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
3536 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
3537 IMFAttributes_Release(attributes
);
3539 /* no output type is available before an input type is set */
3541 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3542 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3544 /* setting output media type first doesn't work */
3545 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3546 check_mft_get_output_current_type(transform
, NULL
);
3548 /* check available input types */
3551 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3553 winetest_push_context("in %lu", i
);
3554 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3555 check_media_type(media_type
, default_inputs
[i
], -1);
3556 ret
= IMFMediaType_Release(media_type
);
3557 ok(ret
== 0, "Release returned %lu\n", ret
);
3558 winetest_pop_context();
3560 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3561 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
3563 check_mft_set_input_type_required(transform
, input_type_desc
);
3564 check_mft_set_input_type(transform
, input_type_desc
);
3565 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3567 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3568 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3570 /* output types can now be enumerated (though they are actually the same for all input types) */
3573 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3575 winetest_push_context("out %lu", i
);
3576 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3577 check_media_type(media_type
, default_outputs
[i
], -1);
3578 ret
= IMFMediaType_Release(media_type
);
3579 ok(ret
== 0, "Release returned %lu\n", ret
);
3580 winetest_pop_context();
3582 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3583 ok(i
== 5, "%lu output media types\n", i
);
3585 check_mft_set_output_type_required(transform
, output_type_desc
);
3586 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3587 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3589 /* check that the output media type we've selected don't change the enumeration */
3592 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3594 winetest_push_context("out %lu", i
);
3595 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3596 check_media_type(media_type
, default_outputs
[i
], -1);
3597 ret
= IMFMediaType_Release(media_type
);
3598 ok(ret
== 0, "Release returned %lu\n", ret
);
3599 winetest_pop_context();
3601 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3602 ok(i
== 5, "%lu output media types\n", i
);
3604 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3605 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3607 load_resource(L
"h264data.bin", &h264_encoded_data
, &h264_encoded_data_len
);
3609 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3610 * IMFTransform_ProcessOutput needs a sample or returns an error */
3612 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3613 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3614 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3617 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3620 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3621 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3622 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
3624 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3625 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3626 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3627 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3628 ok(length
== 0, "got length %lu\n", length
);
3629 ret
= IMFSample_Release(output_sample
);
3630 ok(ret
== 0, "Release returned %lu\n", ret
);
3632 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3633 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3634 ret
= IMFSample_Release(input_sample
);
3635 ok(ret
<= 1, "Release returned %lu\n", ret
);
3636 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3638 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3639 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3640 ret
= IMFSample_Release(input_sample
);
3641 ok(ret
<= 1, "Release returned %lu\n", ret
);
3642 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3645 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3646 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3649 ok(i
== 2, "got %lu iterations\n", i
);
3651 ok(h264_encoded_data_len
== 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
3652 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3653 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3654 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3655 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3656 ok(length
== 0, "got length %lu\n", length
);
3657 ret
= IMFSample_Release(output_sample
);
3658 ok(ret
== 0, "Release returned %lu\n", ret
);
3660 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3661 check_mft_get_output_stream_info(transform
, S_OK
, &actual_output_info
);
3664 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3666 winetest_push_context("out %lu", i
);
3667 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3668 check_media_type(media_type
, actual_outputs
[i
], -1);
3669 ret
= IMFMediaType_Release(media_type
);
3670 ok(ret
== 0, "Release returned %lu\n", ret
);
3671 winetest_pop_context();
3673 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3674 ok(i
== 5, "%lu output media types\n", i
);
3676 /* current output type is still the one we selected */
3677 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3679 hr
= MFCreateCollection(&output_samples
);
3680 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3682 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3683 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3684 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3685 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3686 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3687 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3688 ref
= IMFSample_Release(output_sample
);
3689 ok(ref
== 1, "Release returned %ld\n", ref
);
3691 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
3692 ok(ret
== 0, "got %lu%% diff\n", ret
);
3693 IMFCollection_Release(output_samples
);
3695 /* we can change it, but only with the correct frame size */
3696 hr
= MFCreateMediaType(&media_type
);
3697 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
3698 init_media_type(media_type
, output_type_desc
, -1);
3699 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3700 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
3701 init_media_type(media_type
, new_output_type_desc
, -1);
3702 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3703 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
3704 ret
= IMFMediaType_Release(media_type
);
3705 ok(ret
== 1, "Release returned %lu\n", ret
);
3707 check_mft_get_output_current_type_(transform
, expect_new_output_type_desc
, FALSE
, TRUE
);
3709 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3710 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3712 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3714 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3716 while (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
3718 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3719 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3720 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3721 ret
= IMFSample_Release(input_sample
);
3722 ok(ret
<= 1, "Release returned %lu\n", ret
);
3723 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3724 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3727 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3728 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3730 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3731 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3732 ok(length
== 0, "got length %lu\n", length
);
3733 ret
= IMFSample_Release(output_sample
);
3734 ok(ret
== 0, "Release returned %lu\n", ret
);
3736 hr
= MFCreateCollection(&output_samples
);
3737 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3739 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3740 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3741 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3742 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3743 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3744 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3745 ref
= IMFSample_Release(output_sample
);
3746 ok(ref
== 1, "Release returned %ld\n", ref
);
3748 ret
= check_mf_sample_collection(output_samples
, &expect_output_sample_i420
, L
"i420frame.bmp");
3749 ok(ret
== 0, "got %lu%% diff\n", ret
);
3750 IMFCollection_Release(output_samples
);
3752 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3753 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3754 todo_wine_if(hr
== S_OK
) /* when VA-API plugin is used */
3755 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3756 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3757 ret
= IMFSample_Release(output_sample
);
3758 ok(ret
== 0, "Release returned %lu\n", ret
);
3760 ret
= IMFTransform_Release(transform
);
3761 ok(ret
== 0, "Release returned %lu\n", ret
);
3762 ret
= IMFSample_Release(input_sample
);
3763 ok(ret
== 0, "Release returned %lu\n", ret
);
3766 winetest_pop_context();
3770 static void test_audio_convert(void)
3772 const GUID
*const class_id
= &CLSID_CResamplerMediaObject
;
3773 const struct transform_info expect_mft_info
=
3775 .name
= L
"Resampler MFT",
3776 .major_type
= &MFMediaType_Audio
,
3779 {.subtype
= &MFAudioFormat_PCM
},
3780 {.subtype
= &MFAudioFormat_Float
},
3784 {.subtype
= &MFAudioFormat_PCM
},
3785 {.subtype
= &MFAudioFormat_Float
},
3788 const struct transform_info expect_dmo_info
=
3790 .name
= L
"Resampler DMO",
3791 .major_type
= &MEDIATYPE_Audio
,
3794 {.subtype
= &MEDIASUBTYPE_PCM
},
3795 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3799 {.subtype
= &MEDIASUBTYPE_PCM
},
3800 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3804 static const media_type_desc expect_available_inputs
[] =
3807 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3808 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3809 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3812 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3813 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3814 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3817 static const media_type_desc expect_available_outputs
[] =
3820 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3821 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3822 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3825 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3826 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3827 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3830 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3831 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3832 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3833 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3834 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3835 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
3836 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3837 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3838 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3841 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3842 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3843 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3844 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3845 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
3846 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
3847 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3848 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3849 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3853 static const struct attribute_desc input_type_desc
[] =
3855 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3856 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
3857 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3858 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
3859 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
3860 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
3861 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
3864 const struct attribute_desc output_type_desc
[] =
3866 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3867 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
3868 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3869 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
3870 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
3871 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
3872 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 44100, .required
= TRUE
),
3875 static const struct attribute_desc expect_input_type_desc
[] =
3877 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3878 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3879 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3880 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3881 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3882 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3883 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
3884 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3885 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
3888 const struct attribute_desc expect_output_type_desc
[] =
3890 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3891 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3892 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3893 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3894 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
3895 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3896 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 4),
3897 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3898 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3901 const MFT_OUTPUT_STREAM_INFO output_info
=
3906 const MFT_INPUT_STREAM_INFO input_info
=
3912 static const ULONG audioconv_block_size
= 0x4000;
3913 const struct buffer_desc output_buffer_desc
[] =
3915 {.length
= audioconv_block_size
, .compare
= compare_pcm16
},
3916 {.length
= 0x3dd8, .compare
= compare_pcm16
, .todo_length
= TRUE
},
3917 {.length
= 0xfc, .compare
= compare_pcm16
},
3919 const struct attribute_desc output_sample_attributes
[] =
3921 ATTR_UINT32(mft_output_sample_incomplete
, 1),
3922 ATTR_UINT32(MFSampleExtension_CleanPoint
, has_video_processor
/* 0 on Win7 */, .todo
= TRUE
),
3925 const struct sample_desc output_sample_desc
[] =
3928 .attributes
= output_sample_attributes
+ 0,
3929 .sample_time
= 0, .sample_duration
= 928798,
3930 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 9,
3933 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
3934 .sample_time
= 9287980, .sample_duration
= 897506,
3935 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
3938 .attributes
= output_sample_attributes
+ 0,
3939 .sample_time
= 10185486, .sample_duration
= 14286,
3940 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 2,
3944 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
3945 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
3946 IMFSample
*input_sample
, *output_sample
;
3947 IMFCollection
*output_samples
;
3948 DWORD length
, output_status
;
3949 IMFMediaType
*media_type
;
3950 IMFTransform
*transform
;
3951 const BYTE
*audio_data
;
3952 ULONG audio_data_len
;
3956 hr
= CoInitialize(NULL
);
3957 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3959 winetest_push_context("resampler");
3961 if (!check_mft_enum(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, class_id
))
3963 check_mft_get_info(class_id
, &expect_mft_info
);
3964 check_dmo_get_info(class_id
, &expect_dmo_info
);
3966 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3967 &IID_IMFTransform
, (void **)&transform
)))
3970 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3971 check_interface(transform
, &IID_IMediaObject
, TRUE
);
3972 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
3973 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
3974 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
3976 check_mft_optional_methods(transform
, 1);
3977 check_mft_get_attributes(transform
, NULL
, FALSE
);
3978 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3979 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3982 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3984 winetest_push_context("out %lu", i
);
3985 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3986 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3987 ret
= IMFMediaType_Release(media_type
);
3988 ok(ret
== 0, "Release returned %lu\n", ret
);
3989 winetest_pop_context();
3991 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3992 ok(i
== 4, "%lu output media types\n", i
);
3995 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3997 winetest_push_context("in %lu", i
);
3998 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3999 check_media_type(media_type
, expect_available_inputs
[i
], -1);
4000 ret
= IMFMediaType_Release(media_type
);
4001 ok(ret
== 0, "Release returned %lu\n", ret
);
4002 winetest_pop_context();
4004 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4005 ok(i
== 2, "%lu input media types\n", i
);
4007 /* setting output media type first doesn't work */
4008 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4009 check_mft_get_output_current_type(transform
, NULL
);
4011 check_mft_set_input_type_required(transform
, input_type_desc
);
4012 check_mft_set_input_type(transform
, input_type_desc
);
4013 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4015 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4016 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4018 /* check new output media types */
4021 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4023 winetest_push_context("out %lu", i
);
4024 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4025 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4026 ret
= IMFMediaType_Release(media_type
);
4027 ok(ret
== 0, "Release returned %lu\n", ret
);
4028 winetest_pop_context();
4030 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4031 ok(i
== 4, "%lu output media types\n", i
);
4033 check_mft_set_output_type_required(transform
, output_type_desc
);
4034 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4035 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4037 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4038 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
4040 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
4041 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
4043 input_sample
= create_sample(audio_data
, audio_data_len
);
4044 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4045 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4046 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
4047 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4048 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4049 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4050 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4051 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4052 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4053 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
4054 ret
= IMFSample_Release(input_sample
);
4055 ok(ret
<= 1, "Release returned %ld\n", ret
);
4057 hr
= MFCreateCollection(&output_samples
);
4058 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4060 output_sample
= create_sample(NULL
, audioconv_block_size
);
4061 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
4063 winetest_push_context("%lu", i
);
4064 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4065 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
4066 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4067 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4068 ref
= IMFSample_Release(output_sample
);
4069 ok(ref
== 1, "Release returned %ld\n", ref
);
4070 output_sample
= create_sample(NULL
, audioconv_block_size
);
4071 winetest_pop_context();
4073 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4074 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4075 ret
= IMFSample_Release(output_sample
);
4076 ok(ret
== 0, "Release returned %lu\n", ret
);
4078 ok(i
== 12 || broken(i
== 11) /* Win7 */, "got %lu output samples\n", i
);
4080 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"audioconvdata.bin");
4081 ok(ret
== 0, "got %lu%% diff\n", ret
);
4082 IMFCollection_Release(output_samples
);
4084 output_sample
= create_sample(NULL
, audioconv_block_size
);
4085 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4086 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4087 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4088 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
4089 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4090 ok(length
== 0, "got length %lu\n", length
);
4091 ret
= IMFSample_Release(output_sample
);
4092 ok(ret
== 0, "Release returned %lu\n", ret
);
4094 ret
= IMFTransform_Release(transform
);
4095 ok(ret
== 0, "Release returned %lu\n", ret
);
4098 winetest_pop_context();
4102 static void test_wmv_encoder(void)
4104 const GUID
*const class_id
= &CLSID_CWMVXEncMediaObject
;
4105 const struct transform_info expect_mft_info
=
4107 .name
= L
"WMVideo8 Encoder MFT",
4108 .major_type
= &MFMediaType_Video
,
4111 {.subtype
= &MFVideoFormat_IYUV
},
4112 {.subtype
= &MFVideoFormat_I420
},
4113 {.subtype
= &MFVideoFormat_YV12
},
4114 {.subtype
= &MFVideoFormat_NV11
},
4115 {.subtype
= &MFVideoFormat_NV12
},
4116 {.subtype
= &MFVideoFormat_YUY2
},
4117 {.subtype
= &MFVideoFormat_UYVY
},
4118 {.subtype
= &MFVideoFormat_YVYU
},
4119 {.subtype
= &MFVideoFormat_YVU9
},
4120 {.subtype
= &DMOVideoFormat_RGB32
},
4121 {.subtype
= &DMOVideoFormat_RGB24
},
4122 {.subtype
= &DMOVideoFormat_RGB565
},
4123 {.subtype
= &DMOVideoFormat_RGB555
},
4124 {.subtype
= &DMOVideoFormat_RGB8
},
4128 {.subtype
= &MFVideoFormat_WMV1
},
4129 {.subtype
= &MFVideoFormat_WMV2
},
4132 const struct transform_info expect_dmo_info
=
4134 .name
= L
"WMVideo8 Encoder DMO",
4135 .major_type
= &MEDIATYPE_Video
,
4138 {.subtype
= &MEDIASUBTYPE_IYUV
},
4139 {.subtype
= &MEDIASUBTYPE_I420
},
4140 {.subtype
= &MEDIASUBTYPE_YV12
},
4141 {.subtype
= &MEDIASUBTYPE_NV11
},
4142 {.subtype
= &MEDIASUBTYPE_NV12
},
4143 {.subtype
= &MEDIASUBTYPE_YUY2
},
4144 {.subtype
= &MEDIASUBTYPE_UYVY
},
4145 {.subtype
= &MEDIASUBTYPE_YVYU
},
4146 {.subtype
= &MEDIASUBTYPE_YVU9
},
4147 {.subtype
= &MEDIASUBTYPE_RGB32
},
4148 {.subtype
= &MEDIASUBTYPE_RGB24
},
4149 {.subtype
= &MEDIASUBTYPE_RGB565
},
4150 {.subtype
= &MEDIASUBTYPE_RGB555
},
4151 {.subtype
= &MEDIASUBTYPE_RGB8
},
4155 {.subtype
= &MEDIASUBTYPE_WMV1
},
4156 {.subtype
= &MEDIASUBTYPE_WMV2
},
4160 static const media_type_desc expect_available_inputs
[] =
4163 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4164 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
4165 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4166 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4167 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4168 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4169 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4170 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4173 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4174 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
4175 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4176 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4177 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4178 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4179 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4180 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4183 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4184 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
4185 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4186 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4187 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4188 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4189 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4190 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4193 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4194 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
4195 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4196 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4197 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4198 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4199 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4200 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4203 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4204 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4205 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4206 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4207 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4208 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4209 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4210 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4213 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4214 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
4215 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4216 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4217 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4218 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4219 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4220 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4223 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4224 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
4225 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4226 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4227 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4228 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4229 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4230 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4233 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4234 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
4235 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4236 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4237 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4238 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4239 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4240 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4243 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4244 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
4245 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4246 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4247 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4248 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4249 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4250 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4253 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4254 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
4255 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4256 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4257 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4258 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4259 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4260 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4263 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4264 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
4265 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4266 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4267 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4268 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4269 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4270 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4273 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4274 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
4275 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4276 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4277 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4278 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4279 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4280 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4283 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4284 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
),
4285 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4286 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4287 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4288 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4289 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4290 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4293 static const media_type_desc expect_available_outputs
[] =
4296 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4297 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4298 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4299 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4300 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4301 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4304 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4305 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
),
4306 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4307 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4308 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4309 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4313 static const DWORD actual_width
= 96, actual_height
= 96;
4314 const struct attribute_desc input_type_desc
[] =
4316 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4317 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4318 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4319 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
), /* required for SetOutputType */
4322 const struct attribute_desc output_type_desc
[] =
4324 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4325 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
4326 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4327 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4328 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540, .required
= TRUE
),
4332 const struct attribute_desc expect_input_type_desc
[] =
4334 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4335 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4336 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4337 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4338 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4339 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4340 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4341 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4342 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4345 const struct attribute_desc expect_output_type_desc
[] =
4347 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4348 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4349 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4350 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4351 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540),
4352 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4355 static const MFT_OUTPUT_STREAM_INFO empty_output_info
=
4357 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4359 static const MFT_INPUT_STREAM_INFO empty_input_info
=
4361 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4363 static const MFT_OUTPUT_STREAM_INFO expect_output_info
=
4365 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4369 static const MFT_INPUT_STREAM_INFO expect_input_info
=
4371 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4376 const struct buffer_desc output_buffer_desc
[] =
4378 {.length
= -1 /* variable */},
4380 const struct attribute_desc output_sample_attributes_key
[] =
4382 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4385 const struct attribute_desc output_sample_attributes
[] =
4387 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0),
4390 const struct sample_desc output_sample_desc
[] =
4393 .attributes
= output_sample_attributes_key
,
4394 .sample_time
= 0, .sample_duration
= 333333,
4395 .buffer_count
= 1, .buffers
= output_buffer_desc
,
4398 .attributes
= output_sample_attributes
,
4399 .sample_time
= 333333, .sample_duration
= 333333,
4400 .buffer_count
= 1, .buffers
= output_buffer_desc
, .repeat_count
= 4
4404 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
4405 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4406 IMFSample
*input_sample
, *output_sample
;
4407 DWORD status
, length
, output_status
;
4408 MFT_OUTPUT_DATA_BUFFER output
;
4409 IMFCollection
*output_samples
;
4410 const BYTE
*nv12frame_data
;
4411 IMFMediaType
*media_type
;
4412 ULONG nv12frame_data_len
;
4413 IMFTransform
*transform
;
4418 hr
= CoInitialize(NULL
);
4419 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4421 winetest_push_context("wmvenc");
4423 if (!check_mft_enum(MFT_CATEGORY_VIDEO_ENCODER
, &input_type
, &output_type
, class_id
))
4425 check_mft_get_info(class_id
, &expect_mft_info
);
4426 check_dmo_get_info(class_id
, &expect_dmo_info
);
4428 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4429 &IID_IMFTransform
, (void **)&transform
)))
4432 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4433 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4434 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4435 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4437 check_mft_optional_methods(transform
, 2);
4438 check_mft_get_attributes(transform
, NULL
, FALSE
);
4439 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_input_info
);
4440 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
4443 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4445 winetest_push_context("in 0 %lu", i
);
4446 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4447 ret
= IMFMediaType_Release(media_type
);
4448 ok(ret
<= 1, "Release returned %lu\n", ret
);
4449 winetest_pop_context();
4451 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4452 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
4455 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4457 winetest_push_context("out %lu", i
);
4458 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4459 ret
= IMFMediaType_Release(media_type
);
4460 ok(ret
<= 1, "Release returned %lu\n", ret
);
4461 winetest_pop_context();
4463 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4464 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
4466 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4467 check_mft_get_output_current_type(transform
, NULL
);
4469 check_mft_set_input_type_required(transform
, input_type_desc
);
4470 check_mft_set_input_type(transform
, input_type_desc
);
4471 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4473 check_mft_set_output_type_required(transform
, output_type_desc
);
4474 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4475 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4477 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
4478 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
4480 if (!has_video_processor
)
4482 win_skip("Skipping WMV encoder tests on Win7\n");
4486 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
4487 /* skip BMP header and RGB data from the dump */
4488 length
= *(DWORD
*)(nv12frame_data
+ 2);
4489 nv12frame_data_len
= nv12frame_data_len
- length
;
4490 nv12frame_data
= nv12frame_data
+ length
;
4491 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
4493 hr
= MFCreateCollection(&output_samples
);
4494 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4496 for (i
= 0; i
< 5; i
++)
4498 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
4499 hr
= IMFSample_SetSampleTime(input_sample
, i
* 333333);
4500 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4501 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
4502 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4503 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4504 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4505 ref
= IMFSample_Release(input_sample
);
4506 ok(ref
<= 1, "Release returned %ld\n", ref
);
4508 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4509 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4510 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4511 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4512 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4513 ref
= IMFSample_Release(output_sample
);
4514 ok(ref
== 1, "Release returned %ld\n", ref
);
4517 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmvencdata.bin");
4518 ok(ret
== 0, "got %lu%% diff\n", ret
);
4519 IMFCollection_Release(output_samples
);
4521 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4522 status
= 0xdeadbeef;
4523 memset(&output
, 0, sizeof(output
));
4524 output
.pSample
= output_sample
;
4525 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
4526 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4527 ok(output
.pSample
== output_sample
, "got pSample %p\n", output
.pSample
);
4528 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
4529 ok(status
== 0, "got status %#lx\n", status
);
4530 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
4531 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4532 ok(length
== 0, "got length %lu\n", length
);
4533 ret
= IMFSample_Release(output_sample
);
4534 ok(ret
== 0, "Release returned %lu\n", ret
);
4537 ret
= IMFTransform_Release(transform
);
4538 ok(ret
== 0, "Release returned %lu\n", ret
);
4541 winetest_pop_context();
4545 static void test_wmv_decoder(void)
4547 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
4548 const struct transform_info expect_mft_info
=
4550 .name
= L
"WMVideo Decoder MFT",
4551 .major_type
= &MFMediaType_Video
,
4554 {.subtype
= &MFVideoFormat_WMV1
},
4555 {.subtype
= &MFVideoFormat_WMV2
},
4556 {.subtype
= &MFVideoFormat_WMV3
},
4557 {.subtype
= &MEDIASUBTYPE_WMVP
},
4558 {.subtype
= &MEDIASUBTYPE_WVP2
},
4559 {.subtype
= &MEDIASUBTYPE_WMVR
},
4560 {.subtype
= &MEDIASUBTYPE_WMVA
},
4561 {.subtype
= &MFVideoFormat_WVC1
},
4562 {.subtype
= &MFVideoFormat_VC1S
},
4566 {.subtype
= &MFVideoFormat_YV12
},
4567 {.subtype
= &MFVideoFormat_YUY2
},
4568 {.subtype
= &MFVideoFormat_UYVY
},
4569 {.subtype
= &MFVideoFormat_YVYU
},
4570 {.subtype
= &MFVideoFormat_NV11
},
4571 {.subtype
= &MFVideoFormat_NV12
},
4572 {.subtype
= &DMOVideoFormat_RGB32
},
4573 {.subtype
= &DMOVideoFormat_RGB24
},
4574 {.subtype
= &DMOVideoFormat_RGB565
},
4575 {.subtype
= &DMOVideoFormat_RGB555
},
4576 {.subtype
= &DMOVideoFormat_RGB8
},
4579 const struct transform_info expect_dmo_info
=
4581 .name
= L
"WMVideo Decoder DMO",
4582 .major_type
= &MEDIATYPE_Video
,
4585 {.subtype
= &MEDIASUBTYPE_WMV1
},
4586 {.subtype
= &MEDIASUBTYPE_WMV2
},
4587 {.subtype
= &MEDIASUBTYPE_WMV3
},
4588 {.subtype
= &MEDIASUBTYPE_WMVA
},
4589 {.subtype
= &MEDIASUBTYPE_WVC1
},
4590 {.subtype
= &MEDIASUBTYPE_WMVP
},
4591 {.subtype
= &MEDIASUBTYPE_WVP2
},
4592 {.subtype
= &MFVideoFormat_VC1S
},
4596 {.subtype
= &MEDIASUBTYPE_YV12
},
4597 {.subtype
= &MEDIASUBTYPE_YUY2
},
4598 {.subtype
= &MEDIASUBTYPE_UYVY
},
4599 {.subtype
= &MEDIASUBTYPE_YVYU
},
4600 {.subtype
= &MEDIASUBTYPE_NV11
},
4601 {.subtype
= &MEDIASUBTYPE_NV12
},
4602 {.subtype
= &MEDIASUBTYPE_RGB32
},
4603 {.subtype
= &MEDIASUBTYPE_RGB24
},
4604 {.subtype
= &MEDIASUBTYPE_RGB565
},
4605 {.subtype
= &MEDIASUBTYPE_RGB555
},
4606 {.subtype
= &MEDIASUBTYPE_RGB8
},
4610 static const struct attribute_desc expect_common_attributes
[] =
4612 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4615 static const media_type_desc expect_available_inputs
[] =
4617 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
)},
4618 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
)},
4619 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVA
)},
4620 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVP
)},
4621 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WVP2
)},
4622 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV_Unknown
)},
4623 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WVC1
)},
4624 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV3
)},
4625 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_VC1S
)},
4627 static const MFVideoArea actual_aperture
= {.Area
={96,96}};
4628 static const DWORD actual_width
= 96, actual_height
= 96;
4629 const struct attribute_desc expect_output_attributes
[] =
4631 ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
4632 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
4633 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4634 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4635 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4636 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 2),
4639 const media_type_desc expect_available_outputs
[] =
4642 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4643 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4644 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4645 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4646 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4649 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4650 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
4651 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4652 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4653 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4656 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4657 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
4658 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4659 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4660 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4663 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4664 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
4665 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4666 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4667 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4670 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4671 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
4672 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4673 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4674 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4677 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4678 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
4679 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4680 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4681 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4684 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4685 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
4686 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4687 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4688 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4691 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4692 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
4693 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4694 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4695 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4698 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4699 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
4700 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4701 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
4702 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
4705 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4706 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
4707 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4708 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 3),
4709 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3),
4712 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4713 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
4714 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4715 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4716 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4717 /* ATTR_BLOB(MF_MT_PALETTE, ... with 12 elements), */
4720 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4721 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
4722 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4723 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
4724 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
4727 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4728 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB8
),
4729 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4730 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4731 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
),
4732 /* ATTR_BLOB(MF_MT_PALETTE, ... with 904 elements), */
4735 const struct attribute_desc expect_attributes
[] =
4737 ATTR_UINT32(MF_LOW_LATENCY
, 0),
4738 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1),
4739 ATTR_UINT32(MF_SA_D3D_AWARE
, 1),
4740 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0),
4741 /* more attributes from CODECAPI */
4744 const struct attribute_desc input_type_desc
[] =
4746 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4747 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
4748 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4751 const struct attribute_desc output_type_desc
[] =
4753 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4754 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4755 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4758 const struct attribute_desc expect_input_type_desc
[] =
4760 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4761 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4762 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4763 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4766 const struct attribute_desc expect_output_type_desc
[] =
4768 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4769 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4770 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4771 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4772 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4773 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4774 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
4775 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4776 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4779 const MFT_OUTPUT_STREAM_INFO expect_output_info
=
4781 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
4785 const MFT_OUTPUT_STREAM_INFO empty_output_info
=
4787 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
4789 const MFT_INPUT_STREAM_INFO expect_input_info
=
4795 const struct attribute_desc output_sample_attributes
[] =
4797 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4800 const struct buffer_desc output_buffer_desc_nv12
=
4802 .length
= actual_width
* actual_height
* 3 / 2,
4803 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
4805 const struct sample_desc output_sample_desc_nv12
=
4807 .attributes
= output_sample_attributes
,
4808 .sample_time
= 0, .sample_duration
= 333333,
4809 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
4812 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4813 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
4814 IMFSample
*input_sample
, *output_sample
;
4815 IMFCollection
*output_samples
;
4816 IMFMediaType
*media_type
;
4817 IMFTransform
*transform
;
4818 const BYTE
*wmvenc_data
;
4819 ULONG wmvenc_data_len
;
4820 DWORD output_status
;
4824 hr
= CoInitialize(NULL
);
4825 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4827 winetest_push_context("wmvdec");
4829 if (!has_video_processor
)
4831 win_skip("Skipping inconsistent WMV decoder tests on Win7\n");
4835 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
4837 check_mft_get_info(class_id
, &expect_mft_info
);
4838 check_dmo_get_info(class_id
, &expect_dmo_info
);
4840 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4841 &IID_IMFTransform
, (void **)&transform
)))
4844 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4845 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4846 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4847 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4849 check_mft_optional_methods(transform
, 1);
4850 check_mft_get_attributes(transform
, expect_attributes
, TRUE
);
4852 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4854 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
4856 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4858 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
4861 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4863 winetest_push_context("in %lu", i
);
4864 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4865 check_media_type(media_type
, expect_common_attributes
, -1);
4866 check_media_type(media_type
, expect_available_inputs
[i
], -1);
4867 ret
= IMFMediaType_Release(media_type
);
4868 ok(!ret
, "Release returned %lu\n", ret
);
4869 winetest_pop_context();
4872 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4874 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
4876 if (hr
== E_NOTIMPL
)
4879 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4880 check_mft_get_output_current_type(transform
, NULL
);
4882 check_mft_set_input_type_required(transform
, input_type_desc
);
4883 check_mft_set_input_type(transform
, input_type_desc
);
4884 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4887 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4889 winetest_push_context("out %lu", i
);
4890 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4891 check_media_type(media_type
, expect_common_attributes
, -1);
4892 check_media_type(media_type
, expect_output_attributes
, -1);
4893 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4894 ret
= IMFMediaType_Release(media_type
);
4895 ok(!ret
, "Release returned %lu\n", ret
);
4896 winetest_pop_context();
4898 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4899 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
4901 check_mft_set_output_type_required(transform
, output_type_desc
);
4902 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4903 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4905 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
4906 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
4908 load_resource(L
"wmvencdata.bin", &wmvenc_data
, &wmvenc_data_len
);
4910 input_sample
= create_sample(wmvenc_data
+ sizeof(DWORD
), *(DWORD
*)wmvenc_data
);
4911 wmvenc_data_len
-= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
4912 wmvenc_data
+= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
4913 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4914 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4915 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
4916 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4917 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4918 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4919 ret
= IMFSample_Release(input_sample
);
4920 ok(ret
<= 1, "Release returned %ld\n", ret
);
4922 hr
= MFCreateCollection(&output_samples
);
4923 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4925 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4926 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
4928 winetest_push_context("%lu", i
);
4929 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4930 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4931 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4932 ref
= IMFSample_Release(output_sample
);
4933 ok(ref
== 1, "Release returned %ld\n", ref
);
4934 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4935 winetest_pop_context();
4937 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4938 ret
= IMFSample_Release(output_sample
);
4939 ok(ret
== 0, "Release returned %lu\n", ret
);
4940 ok(i
== 1, "got %lu output samples\n", i
);
4942 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
4943 ok(ret
== 0, "got %lu%% diff\n", ret
);
4944 IMFCollection_Release(output_samples
);
4947 ret
= IMFTransform_Release(transform
);
4948 ok(ret
== 0, "Release returned %lu\n", ret
);
4951 winetest_pop_context();
4955 static void test_wmv_decoder_media_object(void)
4957 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
4958 const DMO_MEDIA_TYPE expected_input_types
[] =
4960 {MFMediaType_Video
, MEDIASUBTYPE_WMV1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4961 {MFMediaType_Video
, MEDIASUBTYPE_WMV2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4962 {MFMediaType_Video
, MEDIASUBTYPE_WMVA
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4963 {MFMediaType_Video
, MEDIASUBTYPE_WMVP
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4964 {MFMediaType_Video
, MEDIASUBTYPE_WVP2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4965 {MFMediaType_Video
, MFVideoFormat_WMV_Unknown
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4966 {MFMediaType_Video
, MEDIASUBTYPE_WVC1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4967 {MFMediaType_Video
, MEDIASUBTYPE_WMV3
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4968 {MFMediaType_Video
, MFVideoFormat_VC1S
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
4970 const VIDEOINFOHEADER expected_output_info
[] =
4972 {{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}},
4973 {{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}},
4974 {{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}},
4975 {{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}},
4976 {{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}},
4977 {{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}},
4978 {{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}},
4979 {{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}},
4980 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 32, BI_RGB
, 1024, 0, 0, 0, 0}},
4981 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 24, BI_RGB
, 768, 0, 0, 0, 0}},
4982 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_BITFIELDS
, 512, 0, 0, 0, 0}},
4983 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_RGB
, 512, 0, 0, 0, 0}},
4984 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 8, BI_RGB
, 256, 0, 0, 226, 226}},
4986 const DMO_MEDIA_TYPE expected_output_types
[] =
4988 {MFMediaType_Video
, MEDIASUBTYPE_NV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[0]},
4989 {MFMediaType_Video
, MEDIASUBTYPE_YV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[1]},
4990 {MFMediaType_Video
, MEDIASUBTYPE_IYUV
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[2]},
4991 {MFMediaType_Video
, MEDIASUBTYPE_I420
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[3]},
4992 {MFMediaType_Video
, MEDIASUBTYPE_YUY2
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[4]},
4993 {MFMediaType_Video
, MEDIASUBTYPE_UYVY
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[5]},
4994 {MFMediaType_Video
, MEDIASUBTYPE_YVYU
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[6]},
4995 {MFMediaType_Video
, MEDIASUBTYPE_NV11
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[7]},
4996 {MFMediaType_Video
, MEDIASUBTYPE_RGB32
, TRUE
, FALSE
, 1024, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[8]},
4997 {MFMediaType_Video
, MEDIASUBTYPE_RGB24
, TRUE
, FALSE
, 768, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[9]},
4998 {MFMediaType_Video
, MEDIASUBTYPE_RGB565
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 100, (BYTE
*)&expected_output_info
[10]},
4999 {MFMediaType_Video
, MEDIASUBTYPE_RGB555
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[11]},
5000 {MFMediaType_Video
, MEDIASUBTYPE_RGB8
, TRUE
, FALSE
, 256, FORMAT_VideoInfo
, NULL
, 1112, (BYTE
*)&expected_output_info
[12]},
5002 const POINT test_size
[] = {{16, 16}, {96, 96}, {320, 240}};
5003 DWORD in_count
, out_count
, size
, expected_size
, alignment
;
5004 DMO_MEDIA_TYPE media_type
, *type
;
5005 IMediaObject
*media_object
;
5010 winetest_push_context("wmvdec");
5012 if (!has_video_processor
)
5014 win_skip("Skipping inconsistent WMV decoder media object tests on Win7.\n");
5015 winetest_pop_context();
5019 type
= (DMO_MEDIA_TYPE
*)buffer
;
5021 hr
= CoInitialize(NULL
);
5022 ok(hr
== S_OK
, "CoInitialize failed, hr %#lx.\n", hr
);
5024 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMediaObject
, (void **)&media_object
);
5025 ok(hr
== S_OK
, "CoCreateInstance returned %#lx.\n", hr
);
5027 /* Test GetStreamCount. */
5028 in_count
= out_count
= 0xdeadbeef;
5029 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, &out_count
);
5030 ok(hr
== S_OK
, "GetStreamCount returned %#lx.\n", hr
);
5031 ok(in_count
== 1, "Got unexpected in_count %lu.\n", in_count
);
5032 ok(out_count
== 1, "Got unexpected in_count %lu.\n", out_count
);
5034 /* Test GetStreamCount with invalid arguments. */
5035 in_count
= out_count
= 0xdeadbeef;
5036 hr
= IMediaObject_GetStreamCount(media_object
, NULL
, &out_count
);
5037 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
5038 ok(out_count
== 0xdeadbeef, "Got unexpected out_count %lu.\n", out_count
);
5039 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, NULL
);
5040 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
5041 ok(in_count
== 0xdeadbeef, "Got unexpected in_count %lu.\n", in_count
);
5043 /* Test GetInputType. */
5044 check_dmo_get_input_type(media_object
, expected_input_types
, ARRAY_SIZE(expected_input_types
));
5046 /* Test SetInputType. */
5047 for (i
= 0; i
< ARRAY_SIZE(expected_input_types
); ++i
)
5049 const GUID
*subtype
= &expected_input_types
[i
].subtype
;
5050 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
5051 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
5052 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
5053 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
5054 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
5056 skip("Skipping SetInputType tests for video subtype %s.\n", debugstr_guid(subtype
));
5060 winetest_push_context("in %lu", i
);
5061 check_dmo_set_input_type(media_object
, subtype
);
5062 winetest_pop_context();
5065 /* Test GetOutputType without setting input type. */
5066 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5067 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5068 hr
= IMediaObject_GetOutputType(media_object
, 0, 0, &media_type
);
5069 ok(hr
== DMO_E_TYPE_NOT_SET
, "GetOutputType returned %#lx.\n", hr
);
5071 /* Test GetOutputType after setting input type. */
5072 init_dmo_media_type_video(type
, &expected_input_types
[0].subtype
, 16, 16);
5073 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5074 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5075 check_dmo_get_output_type(media_object
, expected_output_types
, ARRAY_SIZE(expected_output_types
));
5077 /* Test SetOutputType without setting input type. */
5078 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5079 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5080 hr
= IMediaObject_SetOutputType(media_object
, 0, &media_type
, 0);
5081 ok(hr
== DMO_E_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
5083 /* Test SetOutputType after setting input type. */
5084 init_dmo_media_type_video(type
, &expected_input_types
[0].subtype
, 16, 16);
5085 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5086 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5087 check_dmo_set_output_type(media_object
, &MEDIASUBTYPE_RGB24
);
5089 /* Test GetOutputSizeInfo. */
5090 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5091 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5092 hr
= IMediaObject_GetOutputSizeInfo(media_object
, 0, &size
, &alignment
);
5093 ok(hr
== DMO_E_TYPE_NOT_SET
, "GetOutputSizeInfo returned %#lx.\n", hr
);
5095 for (i
= 0; i
< ARRAY_SIZE(expected_output_types
); ++i
)
5097 const GUID
*subtype
= &expected_output_types
[i
].subtype
;
5098 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
)
5099 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
5101 skip("Skipping GetOutputSizeInfo tests for video subtype %s.\n", debugstr_guid(subtype
));
5105 winetest_push_context("out %lu", i
);
5106 for (j
= 0; j
< ARRAY_SIZE(test_size
); ++j
)
5108 init_dmo_media_type_video(type
, &expected_output_types
[i
].subtype
, test_size
[j
].x
, test_size
[j
].y
);
5109 hr
= IMediaObject_SetOutputType(media_object
, 0, type
, 0);
5110 todo_wine_if(IsEqualGUID(subtype
, &MEDIASUBTYPE_NV11
)
5111 || IsEqualGUID(subtype
, &MEDIASUBTYPE_IYUV
))
5112 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5117 alignment
= 0xdeadbeef;
5118 hr
= MFCalculateImageSize(subtype
, test_size
[j
].x
, test_size
[j
].y
, (UINT32
*)&expected_size
);
5119 ok(hr
== S_OK
, "MFCalculateImageSize returned %#lx.\n", hr
);
5121 hr
= IMediaObject_GetOutputSizeInfo(media_object
, 0, &size
, &alignment
);
5122 ok(hr
== S_OK
, "GetOutputSizeInfo returned %#lx.\n", hr
);
5123 ok(size
== expected_size
, "Got unexpected size %lu, expected %lu.\n", size
, expected_size
);
5124 ok(alignment
== 1, "Got unexpected alignment %lu.\n", alignment
);
5126 winetest_pop_context();
5129 ret
= IMediaObject_Release(media_object
);
5130 ok(ret
== 0, "Release returned %lu\n", ret
);
5132 winetest_pop_context();
5135 static void test_color_convert(void)
5137 const GUID
*const class_id
= &CLSID_CColorConvertDMO
;
5138 const struct transform_info expect_mft_info
=
5140 .name
= L
"Color Converter MFT",
5141 .major_type
= &MFMediaType_Video
,
5144 {.subtype
= &MFVideoFormat_YV12
},
5145 {.subtype
= &MFVideoFormat_YUY2
},
5146 {.subtype
= &MFVideoFormat_UYVY
},
5147 {.subtype
= &MFVideoFormat_AYUV
},
5148 {.subtype
= &MFVideoFormat_NV12
},
5149 {.subtype
= &DMOVideoFormat_RGB32
},
5150 {.subtype
= &DMOVideoFormat_RGB565
},
5151 {.subtype
= &MFVideoFormat_I420
},
5152 {.subtype
= &MFVideoFormat_IYUV
},
5153 {.subtype
= &MFVideoFormat_YVYU
},
5154 {.subtype
= &DMOVideoFormat_RGB24
},
5155 {.subtype
= &DMOVideoFormat_RGB555
},
5156 {.subtype
= &DMOVideoFormat_RGB8
},
5157 {.subtype
= &MEDIASUBTYPE_V216
},
5158 {.subtype
= &MEDIASUBTYPE_V410
},
5159 {.subtype
= &MFVideoFormat_NV11
},
5160 {.subtype
= &MFVideoFormat_Y41P
},
5161 {.subtype
= &MFVideoFormat_Y41T
},
5162 {.subtype
= &MFVideoFormat_Y42T
},
5163 {.subtype
= &MFVideoFormat_YVU9
},
5167 {.subtype
= &MFVideoFormat_YV12
},
5168 {.subtype
= &MFVideoFormat_YUY2
},
5169 {.subtype
= &MFVideoFormat_UYVY
},
5170 {.subtype
= &MFVideoFormat_AYUV
},
5171 {.subtype
= &MFVideoFormat_NV12
},
5172 {.subtype
= &DMOVideoFormat_RGB32
},
5173 {.subtype
= &DMOVideoFormat_RGB565
},
5174 {.subtype
= &MFVideoFormat_I420
},
5175 {.subtype
= &MFVideoFormat_IYUV
},
5176 {.subtype
= &MFVideoFormat_YVYU
},
5177 {.subtype
= &DMOVideoFormat_RGB24
},
5178 {.subtype
= &DMOVideoFormat_RGB555
},
5179 {.subtype
= &DMOVideoFormat_RGB8
},
5180 {.subtype
= &MEDIASUBTYPE_V216
},
5181 {.subtype
= &MEDIASUBTYPE_V410
},
5182 {.subtype
= &MFVideoFormat_NV11
},
5185 const struct transform_info expect_dmo_info
=
5187 .name
= L
"Color Converter DMO",
5188 .major_type
= &MEDIATYPE_Video
,
5191 {.subtype
= &MEDIASUBTYPE_YV12
},
5192 {.subtype
= &MEDIASUBTYPE_YUY2
},
5193 {.subtype
= &MEDIASUBTYPE_UYVY
},
5194 {.subtype
= &MEDIASUBTYPE_AYUV
},
5195 {.subtype
= &MEDIASUBTYPE_NV12
},
5196 {.subtype
= &MEDIASUBTYPE_RGB32
},
5197 {.subtype
= &MEDIASUBTYPE_RGB565
},
5198 {.subtype
= &MEDIASUBTYPE_I420
},
5199 {.subtype
= &MEDIASUBTYPE_IYUV
},
5200 {.subtype
= &MEDIASUBTYPE_YVYU
},
5201 {.subtype
= &MEDIASUBTYPE_RGB24
},
5202 {.subtype
= &MEDIASUBTYPE_RGB555
},
5203 {.subtype
= &MEDIASUBTYPE_RGB8
},
5204 {.subtype
= &MEDIASUBTYPE_V216
},
5205 {.subtype
= &MEDIASUBTYPE_V410
},
5206 {.subtype
= &MEDIASUBTYPE_NV11
},
5207 {.subtype
= &MEDIASUBTYPE_Y41P
},
5208 {.subtype
= &MEDIASUBTYPE_Y41T
},
5209 {.subtype
= &MEDIASUBTYPE_Y42T
},
5210 {.subtype
= &MEDIASUBTYPE_YVU9
},
5214 {.subtype
= &MEDIASUBTYPE_YV12
},
5215 {.subtype
= &MEDIASUBTYPE_YUY2
},
5216 {.subtype
= &MEDIASUBTYPE_UYVY
},
5217 {.subtype
= &MEDIASUBTYPE_AYUV
},
5218 {.subtype
= &MEDIASUBTYPE_NV12
},
5219 {.subtype
= &MEDIASUBTYPE_RGB32
},
5220 {.subtype
= &MEDIASUBTYPE_RGB565
},
5221 {.subtype
= &MEDIASUBTYPE_I420
},
5222 {.subtype
= &MEDIASUBTYPE_IYUV
},
5223 {.subtype
= &MEDIASUBTYPE_YVYU
},
5224 {.subtype
= &MEDIASUBTYPE_RGB24
},
5225 {.subtype
= &MEDIASUBTYPE_RGB555
},
5226 {.subtype
= &MEDIASUBTYPE_RGB8
},
5227 {.subtype
= &MEDIASUBTYPE_V216
},
5228 {.subtype
= &MEDIASUBTYPE_V410
},
5229 {.subtype
= &MEDIASUBTYPE_NV11
},
5233 static const media_type_desc expect_available_inputs
[20] =
5235 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5236 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5237 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
5238 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
5239 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
5240 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
5241 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
5242 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
5243 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
5244 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
5245 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
5246 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
5247 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
5248 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
5249 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
5250 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
5251 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
5252 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
5253 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
5254 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
5256 static const media_type_desc expect_available_outputs
[16] =
5258 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5259 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5260 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
5261 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
5262 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
5263 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
5264 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
5265 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
5266 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
5267 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
5268 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
5269 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
5270 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
5271 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
5272 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
5273 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
5275 static const media_type_desc expect_available_common
=
5277 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5278 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5279 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5282 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
5283 static const DWORD actual_width
= 96, actual_height
= 96;
5284 const struct attribute_desc input_type_desc
[] =
5286 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5287 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5288 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5289 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5292 const struct attribute_desc output_type_desc
[] =
5294 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5295 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5296 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5299 const struct attribute_desc expect_input_type_desc
[] =
5301 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5302 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
5303 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5304 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5305 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5306 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5307 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5308 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5309 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5312 const struct attribute_desc expect_output_type_desc
[] =
5314 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5315 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
5316 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5317 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
5318 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
5319 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5320 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5321 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5324 const MFT_OUTPUT_STREAM_INFO output_info
=
5326 .cbSize
= actual_width
* actual_height
* 4,
5329 const MFT_INPUT_STREAM_INFO input_info
=
5331 .cbSize
= actual_width
* actual_height
* 3 / 2,
5335 const struct buffer_desc output_buffer_desc
=
5337 .length
= actual_width
* actual_height
* 4,
5338 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.right
= 82, .bottom
= 84},
5340 const struct attribute_desc output_sample_attributes
[] =
5342 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0, .todo
= TRUE
),
5345 const struct sample_desc output_sample_desc
=
5347 .attributes
= output_sample_attributes
,
5348 .sample_time
= 0, .sample_duration
= 10000000,
5349 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
5352 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
5353 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
5354 IMFSample
*input_sample
, *output_sample
;
5355 IMFCollection
*output_samples
;
5356 DWORD length
, output_status
;
5357 const BYTE
*nv12frame_data
;
5358 ULONG nv12frame_data_len
;
5359 IMFMediaType
*media_type
;
5360 IMFTransform
*transform
;
5364 hr
= CoInitialize(NULL
);
5365 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5367 winetest_push_context("colorconv");
5369 if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, class_id
))
5371 check_mft_get_info(class_id
, &expect_mft_info
);
5372 check_dmo_get_info(class_id
, &expect_dmo_info
);
5374 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5375 &IID_IMFTransform
, (void **)&transform
)))
5378 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5379 check_interface(transform
, &IID_IMediaObject
, TRUE
);
5380 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
5382 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
5384 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
5385 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
5387 check_mft_optional_methods(transform
, 1);
5388 check_mft_get_attributes(transform
, NULL
, FALSE
);
5389 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5390 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5393 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
5395 winetest_push_context("out %lu", i
);
5396 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5397 check_media_type(media_type
, expect_available_common
, -1);
5398 check_media_type(media_type
, expect_available_outputs
[i
], -1);
5399 ret
= IMFMediaType_Release(media_type
);
5400 ok(ret
== 0, "Release returned %lu\n", ret
);
5401 winetest_pop_context();
5403 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5404 ok(i
== 16, "%lu output media types\n", i
);
5407 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5409 winetest_push_context("in %lu", i
);
5410 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5411 check_media_type(media_type
, expect_available_common
, -1);
5412 check_media_type(media_type
, expect_available_inputs
[i
], -1);
5413 ret
= IMFMediaType_Release(media_type
);
5414 ok(ret
== 0, "Release returned %lu\n", ret
);
5415 winetest_pop_context();
5417 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5418 ok(i
== 20, "%lu input media types\n", i
);
5420 check_mft_set_output_type_required(transform
, output_type_desc
);
5421 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
5422 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
5424 check_mft_set_input_type_required(transform
, input_type_desc
);
5425 check_mft_set_input_type(transform
, input_type_desc
);
5426 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
5428 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5429 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5431 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
5432 /* skip BMP header and RGB data from the dump */
5433 length
= *(DWORD
*)(nv12frame_data
+ 2);
5434 nv12frame_data_len
= nv12frame_data_len
- length
;
5435 nv12frame_data
= nv12frame_data
+ length
;
5436 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
5438 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
5439 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5440 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
5441 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
5442 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
5443 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5444 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5445 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5446 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
5447 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
5448 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
5449 ret
= IMFSample_Release(input_sample
);
5450 ok(ret
<= 1, "Release returned %ld\n", ret
);
5452 hr
= MFCreateCollection(&output_samples
);
5453 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
5455 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5456 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5457 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5458 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5459 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5460 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5461 ref
= IMFSample_Release(output_sample
);
5462 ok(ref
== 1, "Release returned %ld\n", ref
);
5464 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame.bmp");
5465 ok(ret
<= 4 /* small and harmless diff in Wine vs Windows */, "got %lu%% diff\n", ret
);
5466 IMFCollection_Release(output_samples
);
5468 output_sample
= create_sample(NULL
, output_info
.cbSize
);
5469 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5470 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5471 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
5472 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
5473 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
5474 ok(length
== 0, "got length %lu\n", length
);
5475 ret
= IMFSample_Release(output_sample
);
5476 ok(ret
== 0, "Release returned %lu\n", ret
);
5478 ret
= IMFTransform_Release(transform
);
5479 ok(ret
== 0, "Release returned %ld\n", ret
);
5482 winetest_pop_context();
5486 static void test_video_processor(void)
5488 const GUID
*const class_id
= &CLSID_VideoProcessorMFT
;
5489 const struct transform_info expect_mft_info
=
5491 .name
= L
"Microsoft Video Processor MFT",
5492 .major_type
= &MFMediaType_Video
,
5495 {.subtype
= &MFVideoFormat_IYUV
},
5496 {.subtype
= &MFVideoFormat_YV12
},
5497 {.subtype
= &MFVideoFormat_NV12
},
5498 {.subtype
= &MFVideoFormat_YUY2
},
5499 {.subtype
= &MFVideoFormat_ARGB32
},
5500 {.subtype
= &MFVideoFormat_RGB32
},
5501 {.subtype
= &MFVideoFormat_NV11
},
5502 {.subtype
= &MFVideoFormat_AYUV
},
5503 {.subtype
= &MFVideoFormat_UYVY
},
5504 {.subtype
= &MEDIASUBTYPE_P208
},
5505 {.subtype
= &MFVideoFormat_RGB24
},
5506 {.subtype
= &MFVideoFormat_RGB555
},
5507 {.subtype
= &MFVideoFormat_RGB565
},
5508 {.subtype
= &MFVideoFormat_RGB8
},
5509 {.subtype
= &MFVideoFormat_I420
},
5510 {.subtype
= &MFVideoFormat_Y216
},
5511 {.subtype
= &MFVideoFormat_v410
},
5512 {.subtype
= &MFVideoFormat_Y41P
},
5513 {.subtype
= &MFVideoFormat_Y41T
},
5514 {.subtype
= &MFVideoFormat_Y42T
},
5515 {.subtype
= &MFVideoFormat_YVYU
},
5516 {.subtype
= &MFVideoFormat_420O
},
5520 {.subtype
= &MFVideoFormat_IYUV
},
5521 {.subtype
= &MFVideoFormat_YV12
},
5522 {.subtype
= &MFVideoFormat_NV12
},
5523 {.subtype
= &MFVideoFormat_YUY2
},
5524 {.subtype
= &MFVideoFormat_ARGB32
},
5525 {.subtype
= &MFVideoFormat_RGB32
},
5526 {.subtype
= &MFVideoFormat_NV11
},
5527 {.subtype
= &MFVideoFormat_AYUV
},
5528 {.subtype
= &MFVideoFormat_UYVY
},
5529 {.subtype
= &MEDIASUBTYPE_P208
},
5530 {.subtype
= &MFVideoFormat_RGB24
},
5531 {.subtype
= &MFVideoFormat_RGB555
},
5532 {.subtype
= &MFVideoFormat_RGB565
},
5533 {.subtype
= &MFVideoFormat_RGB8
},
5534 {.subtype
= &MFVideoFormat_I420
},
5535 {.subtype
= &MFVideoFormat_Y216
},
5536 {.subtype
= &MFVideoFormat_v410
},
5537 {.subtype
= &MFVideoFormat_Y41P
},
5538 {.subtype
= &MFVideoFormat_Y41T
},
5539 {.subtype
= &MFVideoFormat_Y42T
},
5540 {.subtype
= &MFVideoFormat_YVYU
},
5543 const GUID expect_available_inputs_w8
[] =
5554 MFVideoFormat_ARGB32
,
5555 MFVideoFormat_RGB32
,
5556 MFVideoFormat_RGB24
,
5559 MFVideoFormat_RGB555
,
5560 MFVideoFormat_RGB565
,
5568 const GUID expect_available_inputs_w10
[] =
5584 MFVideoFormat_ARGB32
,
5585 MFVideoFormat_ABGR32
,
5586 MFVideoFormat_RGB32
,
5587 MFVideoFormat_A2R10G10B10
,
5588 MFVideoFormat_A16B16G16R16F
,
5589 MFVideoFormat_RGB24
,
5592 MFVideoFormat_RGB555
,
5593 MFVideoFormat_RGB565
,
5601 const GUID expect_available_outputs
[] =
5603 MFVideoFormat_A2R10G10B10
, /* enumerated with MFVideoFormat_P010 input */
5604 MFVideoFormat_P010
, /* enumerated with MFVideoFormat_A2R10G10B10 input */
5609 MFVideoFormat_RGB24
,
5610 MFVideoFormat_ARGB32
,
5611 MFVideoFormat_RGB32
,
5613 MFVideoFormat_Y216
, /* enumerated with some input formats */
5614 MFVideoFormat_UYVY
, /* enumerated with some input formats */
5615 MFVideoFormat_YVYU
, /* enumerated with some input formats */
5617 MFVideoFormat_RGB555
,
5618 MFVideoFormat_RGB565
,
5619 MFVideoFormat_AYUV
, /* some inputs enumerate MFVideoFormat_AYUV after RGB565 */
5620 MFVideoFormat_NV12
, /* P010 enumerates NV12 after (A)RGB32 formats */
5621 MFVideoFormat_A16B16G16R16F
, /* enumerated with MFVideoFormat_P010 input */
5623 static const media_type_desc expect_available_common
=
5625 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5627 static const struct attribute_desc expect_transform_attributes
[] =
5629 ATTR_UINT32(MFT_SUPPORT_3DVIDEO
, 1, .todo
= TRUE
),
5630 /* ATTR_UINT32(MF_SA_D3D_AWARE, 1), only on W7 */
5634 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
5635 static const DWORD actual_width
= 96, actual_height
= 96;
5636 const struct attribute_desc input_type_desc
[] =
5638 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5639 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5640 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5641 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5644 const struct attribute_desc output_type_desc
[] =
5646 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5647 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5648 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5649 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
5652 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0};
5653 const MFT_INPUT_STREAM_INFO initial_input_info
= {0};
5654 MFT_OUTPUT_STREAM_INFO output_info
= {0};
5655 MFT_INPUT_STREAM_INFO input_info
= {0};
5657 const struct buffer_desc output_buffer_desc
=
5659 .length
= actual_width
* actual_height
* 4,
5660 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
5662 const struct attribute_desc output_sample_attributes
[] =
5664 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1, .todo
= TRUE
),
5667 const struct sample_desc output_sample_desc
=
5669 .attributes
= output_sample_attributes
,
5670 .sample_time
= 0, .sample_duration
= 10000000,
5671 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
5674 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
5675 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
5676 DWORD i
, j
, k
, flags
, length
, output_status
;
5677 IMFSample
*input_sample
, *output_sample
;
5678 IMFMediaType
*media_type
, *media_type2
;
5679 const GUID
*expect_available_inputs
;
5680 IMFCollection
*output_samples
;
5681 const BYTE
*nv12frame_data
;
5682 ULONG nv12frame_data_len
;
5683 IMFTransform
*transform
;
5684 IMFMediaBuffer
*buffer
;
5691 hr
= CoInitialize(NULL
);
5692 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5694 winetest_push_context("videoproc");
5696 if (!check_mft_enum(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, class_id
))
5698 check_mft_get_info(class_id
, &expect_mft_info
);
5700 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5701 &IID_IMFTransform
, (void **)&transform
)))
5705 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
5707 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
5708 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
5709 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
5711 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
5712 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5714 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
5715 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5717 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5718 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5720 check_mft_get_input_current_type(transform
, NULL
);
5721 check_mft_get_output_current_type(transform
, NULL
);
5723 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
5724 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5726 /* Configure stream types. */
5729 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
5731 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
5735 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
5736 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
5737 ok(media_type
!= media_type2
, "Unexpected instance.\n");
5738 ref
= IMFMediaType_Release(media_type2
);
5739 ok(ref
== 0, "Release returned %ld\n", ref
);
5741 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
5742 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
5743 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
5745 hr
= IMFMediaType_GetCount(media_type
, &count
);
5746 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
5747 ok(count
== 2, "Unexpected count %u.\n", count
);
5749 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5750 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
5751 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
5753 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
5754 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
5756 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5757 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
5759 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
5760 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
5762 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
5763 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
5764 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
5765 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
5767 ref
= IMFMediaType_Release(media_type
);
5768 ok(ref
== 0, "Release returned %ld\n", ref
);
5772 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
5773 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5775 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
5776 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
5778 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5779 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
5781 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
5782 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
5783 ok(media_type
!= media_type2
, "Unexpected instance.\n");
5784 IMFMediaType_Release(media_type2
);
5786 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
5787 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
5788 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
5790 input_info
.cbSize
= 0;
5791 if (!IsEqualGUID(&guid
, &MFVideoFormat_P208
) && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y41T
)
5792 && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y42T
))
5794 hr
= MFCalculateImageSize(&guid
, 16, 16, (UINT32
*)&input_info
.cbSize
);
5795 todo_wine_if(IsEqualGUID(&guid
, &MFVideoFormat_Y216
)
5796 || IsEqualGUID(&guid
, &MFVideoFormat_v410
)
5797 || IsEqualGUID(&guid
, &MFVideoFormat_Y41P
))
5798 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5800 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5801 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5803 IMFMediaType_Release(media_type
);
5807 hr
= MFCreateMediaType(&media_type
);
5808 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
5810 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
5811 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5813 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
5814 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5816 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
5817 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5819 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5820 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
5822 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
5823 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
5825 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
5826 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
5828 hr
= MFCalculateImageSize(&MFVideoFormat_IYUV
, 16, 16, (UINT32
*)&input_info
.cbSize
);
5829 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5830 hr
= MFCalculateImageSize(&MFVideoFormat_RGB32
, 16, 16, (UINT32
*)&output_info
.cbSize
);
5831 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5832 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
5833 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
5835 hr
= MFCreateSample(&input_sample
);
5836 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5838 hr
= MFCreateSample(&output_sample
);
5839 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
5841 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5843 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
5845 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5847 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
5849 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5851 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
5853 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5855 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
5857 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5858 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
5859 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5861 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
5863 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
5864 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
5866 hr
= IMFSample_AddBuffer(input_sample
, buffer
);
5867 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5869 hr
= IMFSample_AddBuffer(output_sample
, buffer
);
5870 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
5872 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5874 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
5878 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
5879 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
5882 ref
= IMFTransform_Release(transform
);
5883 ok(ref
== 0, "Release returned %ld\n", ref
);
5885 ref
= IMFMediaType_Release(media_type
);
5886 ok(ref
== 0, "Release returned %ld\n", ref
);
5887 ref
= IMFSample_Release(input_sample
);
5888 ok(ref
== 0, "Release returned %ld\n", ref
);
5889 ref
= IMFSample_Release(output_sample
);
5890 ok(ref
== 0, "Release returned %ld\n", ref
);
5891 ref
= IMFMediaBuffer_Release(buffer
);
5892 ok(ref
== 0, "Release returned %ld\n", ref
);
5895 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
5896 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
5898 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5899 check_interface(transform
, &IID_IMediaObject
, FALSE
);
5900 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
5901 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
5903 check_mft_optional_methods(transform
, 1);
5904 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
5905 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
5906 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
5908 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5909 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5911 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 23, &media_type
);
5912 ok(hr
== S_OK
|| hr
== MF_E_NO_MORE_TYPES
/* w8 */, "GetOutputAvailableType returned %#lx\n", hr
);
5913 if (hr
== MF_E_NO_MORE_TYPES
)
5914 expect_available_inputs
= expect_available_inputs_w8
;
5917 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 27, &media_type
);
5918 ok(hr
== S_OK
|| broken(hr
== MF_E_NO_MORE_TYPES
) /* w1064v1507 */, "GetOutputAvailableType returned %#lx\n", hr
);
5919 if (hr
== MF_E_NO_MORE_TYPES
)
5920 expect_available_inputs
= expect_available_inputs_w10
+ 3;
5922 expect_available_inputs
= expect_available_inputs_w10
;
5926 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5928 /* FIXME: Skip exotic input types which aren't directly accepted */
5929 if (IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L8
)
5930 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_L16
)
5931 || IsEqualGUID(&expect_available_inputs
[i
], &MFAudioFormat_MPEG
)
5932 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_420O
)
5933 || IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_A16B16G16R16F
) /* w1064v1507 */)
5936 winetest_push_context("in %lu", i
);
5937 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5938 check_media_type(media_type
, expect_available_common
, -1);
5940 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5941 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
5943 /* w1064v1507 doesn't expose MFVideoFormat_ABGR32 input */
5944 if (broken(IsEqualGUID(&expect_available_inputs
[i
], &MFVideoFormat_ABGR32
)
5945 && IsEqualGUID(&guid
, &MFVideoFormat_RGB32
)))
5946 expect_available_inputs
++;
5948 ok(IsEqualGUID(&expect_available_inputs
[i
], &guid
), "got subtype %s\n", debugstr_guid(&guid
));
5950 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5951 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
5953 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)actual_width
<< 32 | actual_height
);
5954 ok(hr
== S_OK
, "SetUINT64 returned %#lx.\n", hr
);
5955 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
5956 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5958 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type2
);
5959 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx.\n", hr
);
5960 hr
= IMFMediaType_IsEqual(media_type
, media_type2
, &flags
);
5961 ok(hr
== S_OK
, "IsEqual returned %#lx.\n", hr
);
5962 IMFMediaType_Release(media_type2
);
5964 ret
= IMFMediaType_Release(media_type
);
5965 ok(ret
== 1, "Release returned %lu\n", ret
);
5968 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++j
, &media_type
)))
5970 winetest_push_context("out %lu", j
);
5971 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5972 check_media_type(media_type
, expect_available_common
, -1);
5974 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
5975 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
5977 for (; k
< ARRAY_SIZE(expect_available_outputs
); k
++)
5978 if (IsEqualGUID(&expect_available_outputs
[k
], &guid
))
5980 ok(k
< ARRAY_SIZE(expect_available_outputs
), "got subtype %s\n", debugstr_guid(&guid
));
5982 ret
= IMFMediaType_Release(media_type
);
5983 ok(ret
== 0, "Release returned %lu\n", ret
);
5984 winetest_pop_context();
5986 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5988 winetest_pop_context();
5990 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5991 ok(i
== 22 || i
== 30 || broken(i
== 26) /* w1064v1507 */, "%lu input media types\n", i
);
5993 check_mft_set_input_type_required(transform
, input_type_desc
);
5994 check_mft_set_input_type(transform
, input_type_desc
);
5995 check_mft_get_input_current_type(transform
, input_type_desc
);
5997 check_mft_set_output_type_required(transform
, output_type_desc
);
5998 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
5999 check_mft_get_output_current_type(transform
, output_type_desc
);
6001 input_info
.cbSize
= actual_width
* actual_height
* 3 / 2;
6002 output_info
.cbSize
= actual_width
* actual_height
* 4;
6003 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6004 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6006 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
6007 /* skip BMP header and RGB data from the dump */
6008 length
= *(DWORD
*)(nv12frame_data
+ 2);
6009 nv12frame_data_len
= nv12frame_data_len
- length
;
6010 nv12frame_data
= nv12frame_data
+ length
;
6011 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
6013 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
6014 hr
= IMFSample_SetSampleTime(input_sample
, 0);
6015 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
6016 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
6017 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
6018 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6019 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6020 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6021 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6022 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6023 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6024 ret
= IMFSample_Release(input_sample
);
6025 ok(ret
<= 1, "Release returned %ld\n", ret
);
6027 hr
= MFCreateCollection(&output_samples
);
6028 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
6030 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6031 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6032 ok(hr
== S_OK
|| broken(hr
== MF_E_SHUTDOWN
) /* w8 */, "ProcessOutput returned %#lx\n", hr
);
6035 win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n");
6038 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6040 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6041 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6042 ref
= IMFSample_Release(output_sample
);
6043 ok(ref
== 1, "Release returned %ld\n", ref
);
6045 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, L
"rgb32frame-vp.bmp");
6047 ok(ret
== 0 || broken(ret
== 25) /* w1064v1507 / w1064v1809 incorrectly rescale */, "got %lu%% diff\n", ret
);
6048 IMFCollection_Release(output_samples
);
6050 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6051 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6052 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6053 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6054 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6055 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6056 ok(length
== 0, "got length %lu\n", length
);
6059 ret
= IMFSample_Release(output_sample
);
6060 ok(ret
== 0, "Release returned %lu\n", ret
);
6062 ret
= IMFTransform_Release(transform
);
6063 ok(ret
== 0, "Release returned %ld\n", ret
);
6066 winetest_pop_context();
6070 static void test_mp3_decoder(void)
6072 const GUID
*const class_id
= &CLSID_CMP3DecMediaObject
;
6073 const struct transform_info expect_mft_info
=
6075 .name
= L
"MP3 Decoder MFT",
6076 .major_type
= &MFMediaType_Audio
,
6079 {.subtype
= &MFAudioFormat_MP3
},
6083 {.subtype
= &MFAudioFormat_PCM
},
6086 const struct transform_info expect_dmo_info
=
6088 .name
= L
"MP3 Decoder DMO",
6089 .major_type
= &MEDIATYPE_Audio
,
6092 {.subtype
= &MFAudioFormat_MP3
},
6096 {.subtype
= &MEDIASUBTYPE_PCM
},
6100 static const ULONG mp3dec_block_size
= 0x1200;
6101 static const media_type_desc expect_available_inputs
[] =
6104 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6105 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
6106 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6109 static const media_type_desc expect_available_outputs
[] =
6112 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6113 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6114 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6115 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6116 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6117 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
6118 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
6119 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6122 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6123 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6124 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6125 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6126 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6127 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6128 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6129 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6132 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6133 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6134 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
6135 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6136 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6137 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
6138 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
6139 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6142 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6143 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
6144 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
6145 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6146 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6147 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
6148 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6149 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6152 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6153 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6154 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6155 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6156 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6157 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
6158 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
6159 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6162 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6163 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6164 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
6165 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
6166 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6167 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050),
6168 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
6169 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6173 const struct attribute_desc input_type_desc
[] =
6175 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
6176 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
, .required
= TRUE
),
6177 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
6178 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6181 static const struct attribute_desc output_type_desc
[] =
6183 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
6184 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
6185 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
6186 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
6187 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
6188 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
6189 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
6192 const struct attribute_desc expect_input_type_desc
[] =
6194 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6195 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
6196 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6197 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6198 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6201 static const struct attribute_desc expect_output_type_desc
[] =
6203 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
6204 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
6205 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
6206 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
6207 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
6208 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
6209 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
6210 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6211 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
6214 const MFT_OUTPUT_STREAM_INFO output_info
=
6216 .cbSize
= mp3dec_block_size
,
6219 const MFT_INPUT_STREAM_INFO input_info
=
6224 const struct buffer_desc output_buffer_desc
[] =
6226 {.length
= 0x9c0, .compare
= compare_pcm16
},
6227 {.length
= mp3dec_block_size
, .compare
= compare_pcm16
},
6229 const struct attribute_desc output_sample_attributes
[] =
6231 ATTR_UINT32(mft_output_sample_incomplete
, 1),
6232 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
6235 const struct sample_desc output_sample_desc
[] =
6238 .attributes
= output_sample_attributes
+ 0,
6239 .sample_time
= 0, .sample_duration
= 282993,
6240 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
6243 .attributes
= output_sample_attributes
+ 0,
6244 .sample_time
= 282993, .sample_duration
= 522449,
6245 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 18,
6248 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
6249 .sample_time
= 10209524, .sample_duration
= 522449,
6250 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1,
6254 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
6255 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_MP3
};
6256 IMFSample
*input_sample
, *output_sample
;
6257 IMFCollection
*output_samples
;
6258 DWORD length
, output_status
;
6259 IMFMediaType
*media_type
;
6260 IMFTransform
*transform
;
6261 const BYTE
*mp3enc_data
;
6262 ULONG mp3enc_data_len
;
6266 hr
= CoInitialize(NULL
);
6267 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6269 winetest_push_context("mp3dec");
6271 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
6273 check_mft_get_info(class_id
, &expect_mft_info
);
6274 check_dmo_get_info(class_id
, &expect_dmo_info
);
6276 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
6277 &IID_IMFTransform
, (void **)&transform
)))
6280 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6281 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6283 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6284 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
6286 check_mft_optional_methods(transform
, 1);
6287 check_mft_get_attributes(transform
, NULL
, FALSE
);
6288 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6289 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6291 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6292 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
6295 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6297 winetest_push_context("in %lu", i
);
6298 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6299 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6300 ret
= IMFMediaType_Release(media_type
);
6301 ok(ret
== 0, "Release returned %lu\n", ret
);
6302 winetest_pop_context();
6305 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6307 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
6309 /* setting output media type first doesn't work */
6310 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
6311 check_mft_get_output_current_type(transform
, NULL
);
6313 check_mft_set_input_type_required(transform
, input_type_desc
);
6314 check_mft_set_input_type(transform
, input_type_desc
);
6315 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
6317 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6318 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6320 /* check new output media types */
6323 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6325 winetest_push_context("out %lu", i
);
6326 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6327 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6328 ret
= IMFMediaType_Release(media_type
);
6329 ok(ret
== 0, "Release returned %lu\n", ret
);
6330 winetest_pop_context();
6332 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6333 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
6335 check_mft_set_output_type_required(transform
, output_type_desc
);
6336 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
6337 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
6339 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6340 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6342 load_resource(L
"mp3encdata.bin", &mp3enc_data
, &mp3enc_data_len
);
6343 ok(mp3enc_data_len
== 6295, "got length %lu\n", mp3enc_data_len
);
6345 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
6346 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6347 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6348 ret
= IMFSample_Release(input_sample
);
6349 ok(ret
== 1, "Release returned %lu\n", ret
);
6351 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
6352 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6353 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6354 ret
= IMFSample_Release(input_sample
);
6355 ok(ret
== 0, "Release returned %lu\n", ret
);
6357 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6358 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6360 hr
= MFCreateCollection(&output_samples
);
6361 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
6363 /* first sample is broken */
6364 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6365 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6366 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6367 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
6368 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6369 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6370 ok(length
== mp3dec_block_size
/* Win8 */ || length
== 0x9c0 /* Win10 */ || length
== 0x900 /* Win7 */,
6371 "got length %lu\n", length
);
6372 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6373 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6374 ref
= IMFSample_Release(output_sample
);
6375 ok(ref
== 1, "Release returned %ld\n", ref
);
6377 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6378 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
6380 winetest_push_context("%lu", i
);
6381 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6382 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
6383 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6384 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6385 ref
= IMFSample_Release(output_sample
);
6386 ok(ref
== 1, "Release returned %ld\n", ref
);
6387 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6388 winetest_pop_context();
6390 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6391 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6392 ret
= IMFSample_Release(output_sample
);
6393 ok(ret
== 0, "Release returned %lu\n", ret
);
6394 ok(i
== 20 || broken(i
== 41) /* Win7 */, "got %lu output samples\n", i
);
6396 if (broken(length
!= 0x9c0))
6397 win_skip("Skipping MP3 decoder output sample checks on Win7 / Win8\n");
6400 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"mp3decdata.bin");
6401 ok(ret
== 0, "got %lu%% diff\n", ret
);
6403 IMFCollection_Release(output_samples
);
6405 output_sample
= create_sample(NULL
, mp3dec_block_size
);
6406 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6407 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6408 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6409 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6410 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6411 ok(length
== 0, "got length %lu\n", length
);
6412 ret
= IMFSample_Release(output_sample
);
6413 ok(ret
== 0, "Release returned %lu\n", ret
);
6415 ret
= IMFTransform_Release(transform
);
6416 ok(ret
== 0, "Release returned %lu\n", ret
);
6419 winetest_pop_context();
6423 START_TEST(transform
)
6427 test_sample_copier();
6428 test_sample_copier_output_processing();
6433 test_h264_decoder();
6436 test_wmv_decoder_media_object();
6437 test_audio_convert();
6438 test_color_convert();
6439 test_video_processor();