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"
42 #include "wine/test.h"
48 DEFINE_GUID(DMOVideoFormat_RGB24
,D3DFMT_R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
49 DEFINE_GUID(DMOVideoFormat_RGB32
,D3DFMT_X8R8G8B8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
50 DEFINE_GUID(DMOVideoFormat_RGB555
,D3DFMT_X1R5G5B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
51 DEFINE_GUID(DMOVideoFormat_RGB565
,D3DFMT_R5G6B5
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
52 DEFINE_GUID(DMOVideoFormat_RGB8
,D3DFMT_P8
,0x524f,0x11ce,0x9f,0x53,0x00,0x20,0xaf,0x0b,0xa7,0x70);
53 DEFINE_GUID(MFAudioFormat_RAW_AAC1
,WAVE_FORMAT_RAW_AAC1
,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
54 DEFINE_GUID(MFVideoFormat_ABGR32
,0x00000020,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
55 DEFINE_GUID(MFVideoFormat_P208
,0x38303250,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
56 DEFINE_GUID(MFVideoFormat_VC1S
,0x53314356,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
57 DEFINE_GUID(MFVideoFormat_WMV_Unknown
,0x7ce12ca9,0xbfbf,0x43d9,0x9d,0x00,0x82,0xb8,0xed,0x54,0x31,0x6b);
58 DEFINE_MEDIATYPE_GUID(MEDIASUBTYPE_IV50
,MAKEFOURCC('I','V','5','0'));
60 DEFINE_GUID(mft_output_sample_incomplete
,0xffffff,0xffff,0xffff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff);
64 IMediaBuffer IMediaBuffer_iface
;
71 static inline struct media_buffer
*impl_from_IMediaBuffer(IMediaBuffer
*iface
)
73 return CONTAINING_RECORD(iface
, struct media_buffer
, IMediaBuffer_iface
);
76 static HRESULT WINAPI
media_buffer_QueryInterface(IMediaBuffer
*iface
, REFIID iid
, void **obj
)
78 if (IsEqualIID(iid
, &IID_IMediaBuffer
)
79 || IsEqualIID(iid
, &IID_IUnknown
))
87 static ULONG WINAPI
media_buffer_AddRef(IMediaBuffer
*iface
)
89 struct media_buffer
*buffer
= impl_from_IMediaBuffer(iface
);
90 return InterlockedIncrement(&buffer
->refcount
);
93 static ULONG WINAPI
media_buffer_Release(IMediaBuffer
*iface
)
95 struct media_buffer
*buffer
= impl_from_IMediaBuffer(iface
);
96 ULONG ref
= InterlockedDecrement(&buffer
->refcount
);
102 static HRESULT WINAPI
media_buffer_SetLength(IMediaBuffer
*iface
, DWORD length
)
104 struct media_buffer
*buffer
= impl_from_IMediaBuffer(iface
);
105 if (length
> buffer
->max_length
)
107 buffer
->length
= length
;
111 static HRESULT WINAPI
media_buffer_GetMaxLength(IMediaBuffer
*iface
, DWORD
*max_length
)
113 struct media_buffer
*buffer
= impl_from_IMediaBuffer(iface
);
116 *max_length
= buffer
->max_length
;
120 static HRESULT WINAPI
media_buffer_GetBufferAndLength(IMediaBuffer
*iface
, BYTE
**data
, DWORD
*length
)
122 struct media_buffer
*buffer
= impl_from_IMediaBuffer(iface
);
123 if (!data
|| ! length
)
125 *data
= buffer
->data
;
126 *length
= buffer
->length
;
130 static IMediaBufferVtbl media_buffer_vtbl
= {
131 media_buffer_QueryInterface
,
133 media_buffer_Release
,
134 media_buffer_SetLength
,
135 media_buffer_GetMaxLength
,
136 media_buffer_GetBufferAndLength
,
139 HRESULT
media_buffer_create(DWORD max_length
, struct media_buffer
**ret
)
141 struct media_buffer
*buffer
;
143 if (!(buffer
= calloc(1, offsetof(struct media_buffer
, data
[max_length
]))))
144 return E_OUTOFMEMORY
;
145 buffer
->IMediaBuffer_iface
.lpVtbl
= &media_buffer_vtbl
;
146 buffer
->refcount
= 1;
148 buffer
->max_length
= max_length
;
153 static BOOL
is_compressed_subtype(const GUID
*subtype
)
155 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV1
)
156 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
157 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
158 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVP
)
159 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
160 || IsEqualGUID(subtype
, &MFVideoFormat_WMV_Unknown
)
161 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
162 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV3
)
163 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
168 static DWORD
subtype_to_compression(const GUID
*subtype
)
170 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB32
)
171 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB24
)
172 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB555
)
173 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
175 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
))
178 return subtype
->Data1
;
181 static DWORD
subtype_to_bpp(const GUID
*subtype
)
183 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
185 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_NV12
)
186 || IsEqualGUID(subtype
, &MEDIASUBTYPE_YV12
)
187 || IsEqualGUID(subtype
, &MEDIASUBTYPE_IYUV
)
188 || IsEqualGUID(subtype
, &MEDIASUBTYPE_I420
)
189 || IsEqualGUID(subtype
, &MEDIASUBTYPE_NV11
))
191 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_YUY2
)
192 || IsEqualGUID(subtype
, &MEDIASUBTYPE_UYVY
)
193 || IsEqualGUID(subtype
, &MEDIASUBTYPE_YVYU
)
194 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
)
195 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB555
))
197 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB24
))
199 else if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB32
))
205 static void load_resource(const WCHAR
*filename
, const BYTE
**data
, DWORD
*length
)
207 HRSRC resource
= FindResourceW(NULL
, filename
, (const WCHAR
*)RT_RCDATA
);
208 ok(resource
!= 0, "FindResourceW failed, error %lu\n", GetLastError());
209 *data
= LockResource(LoadResource(GetModuleHandleW(NULL
), resource
));
210 *length
= SizeofResource(GetModuleHandleW(NULL
), resource
);
213 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
214 static void _expect_ref(IUnknown
* obj
, ULONG expected_refcount
, int line
)
217 IUnknown_AddRef(obj
);
218 refcount
= IUnknown_Release(obj
);
219 ok_(__FILE__
, line
)(refcount
== expected_refcount
, "Unexpected refcount %ld, expected %ld.\n", refcount
,
223 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
224 static void check_interface_(unsigned int line
, void *iface_ptr
, REFIID iid
, BOOL supported
)
226 IUnknown
*iface
= iface_ptr
;
227 HRESULT hr
, expected_hr
;
230 expected_hr
= supported
? S_OK
: E_NOINTERFACE
;
232 hr
= IUnknown_QueryInterface(iface
, iid
, (void **)&unk
);
233 ok_(__FILE__
, line
)(hr
== expected_hr
, "Got hr %#lx, expected %#lx.\n", hr
, expected_hr
);
235 IUnknown_Release(unk
);
238 #define check_member_(file, line, val, exp, fmt, member) \
239 ok_ (file, line)((val).member == (exp).member, "got " #member " " fmt "\n", (val).member)
240 #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
242 void check_attributes_(const char *file
, int line
, IMFAttributes
*attributes
,
243 const struct attribute_desc
*desc
, ULONG limit
)
245 char buffer
[256], *buf
= buffer
;
250 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
252 hr
= IMFAttributes_GetItem(attributes
, desc
[i
].key
, &value
);
253 todo_wine_if(desc
[i
].todo
)
254 ok_(file
, line
)(hr
== S_OK
, "%s missing, hr %#lx\n", debugstr_a(desc
[i
].name
), hr
);
255 if (hr
!= S_OK
) continue;
259 default: sprintf(buffer
, "??"); break;
260 case VT_CLSID
: sprintf(buffer
, "%s", debugstr_guid(value
.puuid
)); break;
261 case VT_UI4
: sprintf(buffer
, "%lu", value
.ulVal
); break;
264 sprintf(buffer
, "%lu:%lu", value
.uhVal
.HighPart
, value
.uhVal
.LowPart
);
266 sprintf(buffer
, "%I64u", value
.uhVal
.QuadPart
);
268 case VT_VECTOR
| VT_UI1
:
269 buf
+= sprintf(buf
, "size %lu, data {", value
.caub
.cElems
);
270 for (j
= 0; j
< 16 && j
< value
.caub
.cElems
; ++j
)
271 buf
+= sprintf(buf
, "0x%02x,", value
.caub
.pElems
[j
]);
272 if (value
.caub
.cElems
> 16)
273 buf
+= sprintf(buf
, "...}");
275 buf
+= sprintf(buf
- (j
? 1 : 0), "}");
279 ret
= PropVariantCompareEx(&value
, &desc
[i
].value
, 0, 0);
280 todo_wine_if(desc
[i
].todo_value
)
281 ok_(file
, line
)(ret
== 0, "%s mismatch, type %u, value %s\n",
282 debugstr_a(desc
[i
].name
), value
.vt
, buffer
);
283 PropVariantClear(&value
);
287 struct transform_info
290 const GUID
*major_type
;
295 } inputs
[32], input_end
, outputs
[32], output_end
;
298 static BOOL
check_mft_enum(GUID category
, MFT_REGISTER_TYPE_INFO
*input_type
,
299 MFT_REGISTER_TYPE_INFO
*output_type
, const GUID
*expect_class_id
)
301 GUID
*class_ids
= NULL
;
305 hr
= MFTEnum(category
, 0, input_type
, output_type
, NULL
, &class_ids
, &count
);
306 if (FAILED(hr
) || count
== 0)
309 win_skip("MFTEnum returned %#lx, count %u, skipping tests.\n", hr
, count
);
313 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
314 for (i
= 0; i
< count
; ++i
)
315 if (IsEqualGUID(expect_class_id
, class_ids
+ i
))
317 ok(i
< count
, "Failed to find transform.\n");
318 CoTaskMemFree(class_ids
);
323 static void check_mft_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
325 MFT_REGISTER_TYPE_INFO
*input_types
= NULL
, *output_types
= NULL
;
326 UINT32 input_count
= 0, output_count
= 0, i
;
330 hr
= MFTGetInfo(*class_id
, &name
, &input_types
, &input_count
, &output_types
, &output_count
, NULL
);
331 ok(hr
== S_OK
, "MFTEnum returned %#lx\n", hr
);
332 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
334 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
336 ok(IsEqualGUID(&input_types
[i
].guidMajorType
, expect
->major_type
),
337 "got input[%u] major %s\n", i
, debugstr_guid(&input_types
[i
].guidMajorType
));
338 ok(IsEqualGUID(&input_types
[i
].guidSubtype
, expect
->inputs
[i
].subtype
),
339 "got input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
341 for (; expect
->inputs
[i
].subtype
; ++i
)
342 ok(broken(expect
->inputs
[i
].broken
), "missing input[%u] subtype %s\n",
343 i
, debugstr_guid(expect
->inputs
[i
].subtype
));
344 for (; i
< input_count
; ++i
)
345 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input_types
[i
].guidSubtype
));
347 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
349 ok(IsEqualGUID(&output_types
[i
].guidMajorType
, expect
->major_type
),
350 "got output[%u] major %s\n", i
, debugstr_guid(&output_types
[i
].guidMajorType
));
351 ok(IsEqualGUID(&output_types
[i
].guidSubtype
, expect
->outputs
[i
].subtype
),
352 "got output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
354 for (; expect
->outputs
[i
].subtype
; ++i
)
355 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
356 for (; i
< output_count
; ++i
)
357 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output_types
[i
].guidSubtype
));
359 CoTaskMemFree(output_types
);
360 CoTaskMemFree(input_types
);
364 static void check_dmo_get_info(const GUID
*class_id
, const struct transform_info
*expect
)
366 DWORD input_count
= 0, output_count
= 0;
367 DMO_PARTIAL_MEDIATYPE output
[32] = {{{0}}};
368 DMO_PARTIAL_MEDIATYPE input
[32] = {{{0}}};
373 hr
= DMOGetName(class_id
, name
);
374 ok(hr
== S_OK
, "DMOGetName returned %#lx\n", hr
);
375 ok(!wcscmp(name
, expect
->name
), "got name %s\n", debugstr_w(name
));
377 hr
= DMOGetTypes(class_id
, ARRAY_SIZE(input
), &input_count
, input
,
378 ARRAY_SIZE(output
), &output_count
, output
);
379 ok(hr
== S_OK
, "DMOGetTypes returned %#lx\n", hr
);
381 for (i
= 0; i
< input_count
&& expect
->inputs
[i
].subtype
; ++i
)
383 ok(IsEqualGUID(&input
[i
].type
, expect
->major_type
),
384 "got input[%u] major %s\n", i
, debugstr_guid(&input
[i
].type
));
385 ok(IsEqualGUID(&input
[i
].subtype
, expect
->inputs
[i
].subtype
),
386 "got input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
388 for (; expect
->inputs
[i
].subtype
; ++i
)
389 ok(0, "missing input[%u] subtype %s\n", i
, debugstr_guid(expect
->inputs
[i
].subtype
));
390 for (; i
< input_count
; ++i
)
391 ok(0, "extra input[%u] subtype %s\n", i
, debugstr_guid(&input
[i
].subtype
));
393 for (i
= 0; expect
->outputs
[i
].subtype
; ++i
)
395 ok(IsEqualGUID(&output
[i
].type
, expect
->major_type
),
396 "got output[%u] major %s\n", i
, debugstr_guid(&output
[i
].type
));
397 ok(IsEqualGUID(&output
[i
].subtype
, expect
->outputs
[i
].subtype
),
398 "got output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
400 for (; expect
->outputs
[i
].subtype
; ++i
)
401 ok(0, "missing output[%u] subtype %s\n", i
, debugstr_guid(expect
->outputs
[i
].subtype
));
402 for (; i
< output_count
; ++i
)
403 ok(0, "extra output[%u] subtype %s\n", i
, debugstr_guid(&output
[i
].subtype
));
406 void init_media_type(IMFMediaType
*mediatype
, const struct attribute_desc
*desc
, ULONG limit
)
411 hr
= IMFMediaType_DeleteAllItems(mediatype
);
412 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
414 for (i
= 0; i
< limit
&& desc
[i
].key
; ++i
)
416 hr
= IMFMediaType_SetItem(mediatype
, desc
[i
].key
, &desc
[i
].value
);
417 ok(hr
== S_OK
, "SetItem %s returned %#lx\n", debugstr_a(desc
[i
].name
), hr
);
421 static void init_dmo_media_type_video(DMO_MEDIA_TYPE
*media_type
,
422 const GUID
*subtype
, const LONG width
, const LONG height
)
424 VIDEOINFOHEADER
*header
= (VIDEOINFOHEADER
*)(media_type
+ 1);
425 BOOL compressed
= is_compressed_subtype(subtype
);
426 ULONG codec_data_size
= compressed
? 4 : 0;
428 memset(media_type
, 0, sizeof(*media_type
) + sizeof(*header
) + codec_data_size
);
430 header
->bmiHeader
.biSize
= sizeof(header
->bmiHeader
);
431 header
->bmiHeader
.biWidth
= width
;
432 header
->bmiHeader
.biHeight
= height
;
433 header
->bmiHeader
.biPlanes
= 1;
434 header
->bmiHeader
.biBitCount
= subtype_to_bpp(subtype
);
435 header
->bmiHeader
.biCompression
= subtype_to_compression(subtype
);
437 media_type
->majortype
= MEDIATYPE_Video
;
438 media_type
->subtype
= *subtype
;
439 media_type
->bFixedSizeSamples
= !compressed
;
440 media_type
->bTemporalCompression
= compressed
;
441 media_type
->lSampleSize
= 0;
442 media_type
->formattype
= FORMAT_VideoInfo
;
443 media_type
->pUnk
= NULL
;
444 media_type
->cbFormat
= sizeof(*header
) + codec_data_size
;
445 media_type
->pbFormat
= (BYTE
*)header
;
448 static void check_mft_optional_methods(IMFTransform
*transform
, DWORD output_count
)
450 DWORD in_id
, out_id
, in_count
, out_count
, in_min
, in_max
, out_min
, out_max
;
451 PROPVARIANT propvar
= {.vt
= VT_EMPTY
};
452 IMFMediaEvent
*event
;
455 in_min
= in_max
= out_min
= out_max
= 0xdeadbeef;
456 hr
= IMFTransform_GetStreamLimits(transform
, &in_min
, &in_max
, &out_min
, &out_max
);
457 ok(hr
== S_OK
, "GetStreamLimits returned %#lx\n", hr
);
458 ok(in_min
== 1, "got input_min %lu\n", in_min
);
459 ok(in_max
== 1, "got input_max %lu\n", in_max
);
460 ok(out_min
== output_count
, "got output_min %lu\n", out_min
);
461 ok(out_max
== output_count
, "got output_max %lu\n", out_max
);
463 in_count
= out_count
= 0xdeadbeef;
464 hr
= IMFTransform_GetStreamCount(transform
, &in_count
, &out_count
);
465 ok(hr
== S_OK
, "GetStreamCount returned %#lx\n", hr
);
466 ok(in_count
== 1, "got input_count %lu\n", in_count
);
467 ok(out_count
== output_count
, "got output_count %lu\n", out_count
);
469 in_count
= out_count
= 1;
470 in_id
= out_id
= 0xdeadbeef;
471 hr
= IMFTransform_GetStreamIDs(transform
, in_count
, &in_id
, out_count
, &out_id
);
472 ok(hr
== E_NOTIMPL
, "GetStreamIDs returned %#lx\n", hr
);
474 hr
= IMFTransform_DeleteInputStream(transform
, 0);
475 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
476 hr
= IMFTransform_DeleteInputStream(transform
, 1);
477 ok(hr
== E_NOTIMPL
, "DeleteInputStream returned %#lx\n", hr
);
479 hr
= IMFTransform_AddInputStreams(transform
, 0, NULL
);
480 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
482 hr
= IMFTransform_AddInputStreams(transform
, 1, &in_id
);
483 ok(hr
== E_NOTIMPL
, "AddInputStreams returned %#lx\n", hr
);
485 hr
= IMFTransform_SetOutputBounds(transform
, 0, 0);
486 ok(hr
== E_NOTIMPL
|| hr
== S_OK
, "SetOutputBounds returned %#lx\n", hr
);
488 hr
= MFCreateMediaEvent(MEEndOfStream
, &GUID_NULL
, S_OK
, &propvar
, &event
);
489 ok(hr
== S_OK
, "MFCreateMediaEvent returned %#lx\n", hr
);
490 hr
= IMFTransform_ProcessEvent(transform
, 0, NULL
);
491 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
|| hr
== E_INVALIDARG
, "ProcessEvent returned %#lx\n", hr
);
492 hr
= IMFTransform_ProcessEvent(transform
, 1, event
);
493 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
494 hr
= IMFTransform_ProcessEvent(transform
, 0, event
);
495 ok(hr
== E_NOTIMPL
, "ProcessEvent returned %#lx\n", hr
);
496 IMFMediaEvent_Release(event
);
499 static void check_mft_get_attributes(IMFTransform
*transform
, const struct attribute_desc
*expect_transform_attributes
,
500 BOOL expect_output_attributes
)
502 IMFAttributes
*attributes
, *tmp_attributes
;
507 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
508 todo_wine_if(expect_transform_attributes
&& hr
== E_NOTIMPL
)
509 ok(hr
== (expect_transform_attributes
? S_OK
: E_NOTIMPL
), "GetAttributes returned %#lx\n", hr
);
512 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
513 check_attributes(attributes
, expect_transform_attributes
, -1);
515 hr
= IMFTransform_GetAttributes(transform
, &tmp_attributes
);
516 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
517 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
518 IMFAttributes_Release(tmp_attributes
);
520 ref
= IMFAttributes_Release(attributes
);
521 ok(ref
== 1, "Release returned %lu\n", ref
);
524 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &attributes
);
525 todo_wine_if(expect_output_attributes
&& hr
== E_NOTIMPL
)
526 ok(hr
== (expect_output_attributes
? S_OK
: E_NOTIMPL
)
527 || broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
528 "GetOutputStreamAttributes returned %#lx\n", hr
);
531 ok(hr
== S_OK
, "GetOutputStreamAttributes returned %#lx\n", hr
);
534 hr
= IMFAttributes_GetCount(attributes
, &count
);
535 ok(hr
== S_OK
, "GetCount returned %#lx\n", hr
);
536 ok(!count
, "got %u attributes\n", count
);
538 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, &tmp_attributes
);
539 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
540 ok(attributes
== tmp_attributes
, "got attributes %p\n", tmp_attributes
);
541 IMFAttributes_Release(tmp_attributes
);
543 ref
= IMFAttributes_Release(attributes
);
544 ok(ref
== 1, "Release returned %lu\n", ref
);
546 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 0, NULL
);
547 ok(hr
== E_NOTIMPL
|| hr
== E_POINTER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
548 hr
= IMFTransform_GetOutputStreamAttributes(transform
, 1, &attributes
);
549 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "GetOutputStreamAttributes returned %#lx\n", hr
);
552 hr
= IMFTransform_GetInputStreamAttributes(transform
, 0, &attributes
);
553 ok(hr
== E_NOTIMPL
|| broken(hr
== MF_E_UNSUPPORTED_REPRESENTATION
) /* Win7 */,
554 "GetInputStreamAttributes returned %#lx\n", hr
);
557 #define check_mft_input_stream_info(a, b) check_mft_input_stream_info_(__LINE__, a, b)
558 static void check_mft_input_stream_info_(int line
, MFT_INPUT_STREAM_INFO
*value
, const MFT_INPUT_STREAM_INFO
*expect
)
560 check_member_(__FILE__
, line
, *value
, *expect
, "%I64d", hnsMaxLatency
);
561 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
562 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
563 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbMaxLookahead
);
564 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
567 #define check_mft_get_input_stream_info(a, b, c) check_mft_get_input_stream_info_(__LINE__, a, b, c)
568 static void check_mft_get_input_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_INPUT_STREAM_INFO
*expect
)
570 MFT_INPUT_STREAM_INFO info
, empty
= {0};
573 memset(&info
, 0xcd, sizeof(info
));
574 hr
= IMFTransform_GetInputStreamInfo(transform
, 0, &info
);
575 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetInputStreamInfo returned %#lx\n", hr
);
576 check_mft_input_stream_info_(line
, &info
, expect
? expect
: &empty
);
579 #define check_mft_output_stream_info(a, b) check_mft_output_stream_info_(__LINE__, a, b)
580 static void check_mft_output_stream_info_(int line
, MFT_OUTPUT_STREAM_INFO
*value
, const MFT_OUTPUT_STREAM_INFO
*expect
)
582 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", dwFlags
);
583 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbSize
);
584 check_member_(__FILE__
, line
, *value
, *expect
, "%#lx", cbAlignment
);
587 #define check_mft_get_output_stream_info(a, b, c) check_mft_get_output_stream_info_(__LINE__, a, b, c)
588 static void check_mft_get_output_stream_info_(int line
, IMFTransform
*transform
, HRESULT expect_hr
, const MFT_OUTPUT_STREAM_INFO
*expect
)
590 MFT_OUTPUT_STREAM_INFO info
, empty
= {0};
593 memset(&info
, 0xcd, sizeof(info
));
594 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
595 ok_(__FILE__
, line
)(hr
== expect_hr
, "GetOutputStreamInfo returned %#lx\n", hr
);
596 check_mft_output_stream_info_(line
, &info
, expect
? expect
: &empty
);
599 #define check_mft_set_input_type_required(a, b) check_mft_set_input_type_required_(__LINE__, a, b)
600 static void check_mft_set_input_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
602 const struct attribute_desc
*attr
;
603 IMFMediaType
*media_type
;
607 hr
= MFCreateMediaType(&media_type
);
608 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
609 init_media_type(media_type
, attributes
, -1);
611 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
613 winetest_push_context("%s", debugstr_a(attr
->name
));
614 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
615 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
616 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
617 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetInputType returned %#lx.\n", hr
);
618 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
619 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
620 winetest_pop_context();
623 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
624 ok_(__FILE__
, line
)(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
625 ref
= IMFMediaType_Release(media_type
);
626 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
629 static void check_mft_set_input_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
)
631 IMFMediaType
*media_type
;
634 hr
= MFCreateMediaType(&media_type
);
635 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
636 init_media_type(media_type
, attributes
, -1);
638 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
639 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
640 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
641 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
643 IMFMediaType_Release(media_type
);
646 #define check_mft_get_input_current_type(a, b) check_mft_get_input_current_type_(a, b, FALSE, FALSE)
647 static void check_mft_get_input_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
648 BOOL todo_current
, BOOL todo_compare
)
650 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
651 IMFMediaType
*media_type
, *current_type
;
654 hr
= IMFTransform_GetInputCurrentType(transform
, 0, ¤t_type
);
655 todo_wine_if(todo_current
)
656 ok(hr
== expect_hr
, "GetInputCurrentType returned hr %#lx.\n", hr
);
660 hr
= MFCreateMediaType(&media_type
);
661 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
662 init_media_type(media_type
, attributes
, -1);
664 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
665 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
666 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
667 todo_wine_if(todo_compare
)
668 ok(result
, "got result %u.\n", !!result
);
670 IMFMediaType_Release(media_type
);
671 IMFMediaType_Release(current_type
);
674 #define check_mft_set_output_type_required(a, b) check_mft_set_output_type_required_(__LINE__, a, b)
675 static void check_mft_set_output_type_required_(int line
, IMFTransform
*transform
, const struct attribute_desc
*attributes
)
677 const struct attribute_desc
*attr
;
678 IMFMediaType
*media_type
;
682 hr
= MFCreateMediaType(&media_type
);
683 ok_(__FILE__
, line
)(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
684 init_media_type(media_type
, attributes
, -1);
686 for (attr
= attributes
; attr
&& attr
->key
; attr
++)
688 winetest_push_context("%s", debugstr_a(attr
->name
));
689 hr
= IMFMediaType_DeleteItem(media_type
, attr
->key
);
690 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
691 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
692 ok_(__FILE__
, line
)(FAILED(hr
) == attr
->required
, "SetOutputType returned %#lx.\n", hr
);
693 hr
= IMFMediaType_SetItem(media_type
, attr
->key
, &attr
->value
);
694 ok_(__FILE__
, line
)(hr
== S_OK
, "SetItem returned %#lx\n", hr
);
695 winetest_pop_context();
698 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
699 ok_(__FILE__
, line
)(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
700 ref
= IMFMediaType_Release(media_type
);
701 ok_(__FILE__
, line
)(!ref
, "Release returned %lu\n", ref
);
704 static void check_mft_set_output_type(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
707 IMFMediaType
*media_type
;
710 hr
= MFCreateMediaType(&media_type
);
711 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
712 init_media_type(media_type
, attributes
, -1);
714 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
715 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
716 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
717 ok(hr
== expect_hr
, "SetOutputType returned %#lx.\n", hr
);
719 IMFMediaType_Release(media_type
);
722 #define check_mft_get_output_current_type(a, b) check_mft_get_output_current_type_(a, b, FALSE, FALSE)
723 static void check_mft_get_output_current_type_(IMFTransform
*transform
, const struct attribute_desc
*attributes
,
724 BOOL todo_current
, BOOL todo_compare
)
726 HRESULT hr
, expect_hr
= attributes
? S_OK
: MF_E_TRANSFORM_TYPE_NOT_SET
;
727 IMFMediaType
*media_type
, *current_type
;
730 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, ¤t_type
);
731 todo_wine_if(todo_current
)
732 ok(hr
== expect_hr
, "GetOutputCurrentType returned hr %#lx.\n", hr
);
736 hr
= MFCreateMediaType(&media_type
);
737 ok(hr
== S_OK
, "MFCreateMediaType returned hr %#lx.\n", hr
);
738 init_media_type(media_type
, attributes
, -1);
740 hr
= IMFMediaType_Compare(current_type
, (IMFAttributes
*)media_type
,
741 MF_ATTRIBUTES_MATCH_ALL_ITEMS
, &result
);
742 ok(hr
== S_OK
, "Compare returned hr %#lx.\n", hr
);
743 todo_wine_if(todo_compare
)
744 ok(result
, "got result %u.\n", !!result
);
746 IMFMediaType_Release(media_type
);
747 IMFMediaType_Release(current_type
);
750 #define check_mft_process_output(a, b, c) check_mft_process_output_(__LINE__, a, b, c)
751 static HRESULT
check_mft_process_output_(int line
, IMFTransform
*transform
, IMFSample
*output_sample
, DWORD
*output_status
)
753 static const DWORD expect_flags
= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
| MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
754 | MFT_OUTPUT_DATA_BUFFER_STREAM_END
| MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
;
755 MFT_OUTPUT_DATA_BUFFER output
[3];
760 memset(&output
, 0, sizeof(output
));
761 output
[0].pSample
= output_sample
;
762 output
[0].dwStreamID
= 0;
763 ret
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
764 ok_(__FILE__
, line
)(output
[0].dwStreamID
== 0, "got dwStreamID %#lx\n", output
[0].dwStreamID
);
765 ok_(__FILE__
, line
)(output
[0].pEvents
== NULL
, "got pEvents %p\n", output
[0].pEvents
);
766 ok_(__FILE__
, line
)(output
[0].pSample
== output_sample
, "got pSample %p\n", output
[0].pSample
);
767 ok_(__FILE__
, line
)((output
[0].dwStatus
& ~expect_flags
) == 0
768 || broken((output
[0].dwStatus
& ~expect_flags
) == 6) /* Win7 */
769 || broken((output
[0].dwStatus
& ~expect_flags
) == 7) /* Win7 */,
770 "got dwStatus %#lx\n", output
[0].dwStatus
);
771 *output_status
= output
[0].dwStatus
& expect_flags
;
774 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
775 else if (ret
== MF_E_TRANSFORM_STREAM_CHANGE
)
776 ok_(__FILE__
, line
)(status
== MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS
,
777 "got status %#lx\n", status
);
780 if (*output_status
& MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
)
782 hr
= IMFSample_SetUINT32(output_sample
, &mft_output_sample_incomplete
, 1);
783 ok_(__FILE__
, line
)(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
787 hr
= IMFSample_DeleteItem(output_sample
, &mft_output_sample_incomplete
);
788 ok_(__FILE__
, line
)(hr
== S_OK
, "DeleteItem returned %#lx\n", hr
);
790 ok_(__FILE__
, line
)(status
== 0, "got status %#lx\n", status
);
796 DWORD
compare_nv12(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
798 DWORD x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
800 /* skip BMP header and RGB data from the dump */
801 size
= *(DWORD
*)(expect
+ 2);
802 *length
= *length
+ size
;
803 expect
= expect
+ size
;
805 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
807 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
808 for (x
= 0; x
< width
; x
++)
810 if (x
< rect
->left
|| x
>= rect
->right
) continue;
811 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
815 for (y
= 0; y
< height
; y
+= 2, data
+= width
, expect
+= width
)
817 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
818 for (x
= 0; x
< width
; x
+= 2)
820 if (x
< rect
->left
|| x
>= rect
->right
) continue;
821 diff
+= abs((int)expect
[x
+ 0] - (int)data
[x
+ 0]);
822 diff
+= abs((int)expect
[x
+ 1] - (int)data
[x
+ 1]);
826 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
827 return diff
* 100 / 256 / size
;
830 DWORD
compare_i420(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
832 DWORD i
, x
, y
, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
834 /* skip BMP header and RGB data from the dump */
835 size
= *(DWORD
*)(expect
+ 2);
836 *length
= *length
+ size
;
837 expect
= expect
+ size
;
839 for (y
= 0; y
< height
; y
++, data
+= width
, expect
+= width
)
841 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
842 for (x
= 0; x
< width
; x
++)
844 if (x
< rect
->left
|| x
>= rect
->right
) continue;
845 diff
+= abs((int)expect
[x
] - (int)data
[x
]);
849 for (i
= 0; i
< 2; ++i
) for (y
= 0; y
< height
; y
+= 2, data
+= width
/ 2, expect
+= width
/ 2)
851 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
852 for (x
= 0; x
< width
; x
+= 2)
854 if (x
< rect
->left
|| x
>= rect
->right
) continue;
855 diff
+= abs((int)expect
[x
/ 2] - (int)data
[x
/ 2]);
859 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * 3 / 2;
860 return diff
* 100 / 256 / size
;
863 static DWORD
compare_rgb(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
, UINT bits
)
865 DWORD x
, y
, step
= bits
/ 8, size
, diff
= 0, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
867 /* skip BMP header from the dump */
868 size
= *(DWORD
*)(expect
+ 2 + 2 * sizeof(DWORD
));
869 *length
= *length
+ size
;
870 expect
= expect
+ size
;
872 for (y
= 0; y
< height
; y
++, data
+= width
* step
, expect
+= width
* step
)
874 if (y
< rect
->top
|| y
>= rect
->bottom
) continue;
875 for (x
= 0; x
< width
; x
++)
877 if (x
< rect
->left
|| x
>= rect
->right
) continue;
878 diff
+= abs((int)expect
[step
* x
+ 0] - (int)data
[step
* x
+ 0]);
879 diff
+= abs((int)expect
[step
* x
+ 1] - (int)data
[step
* x
+ 1]);
880 if (step
>= 3) diff
+= abs((int)expect
[step
* x
+ 2] - (int)data
[step
* x
+ 2]);
884 size
= (rect
->right
- rect
->left
) * (rect
->bottom
- rect
->top
) * min(step
, 3);
885 return diff
* 100 / 256 / size
;
888 DWORD
compare_rgb32(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
890 return compare_rgb(data
, length
, rect
, expect
, 32);
893 DWORD
compare_rgb24(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
895 return compare_rgb(data
, length
, rect
, expect
, 24);
898 DWORD
compare_rgb16(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
900 return compare_rgb(data
, length
, rect
, expect
, 16);
903 DWORD
compare_pcm16(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
905 const INT16
*data_pcm
= (INT16
*)data
, *expect_pcm
= (INT16
*)expect
;
906 DWORD i
, size
= *length
/ 2, diff
= 0;
908 for (i
= 0; i
< size
; i
++)
909 diff
+= abs((int)*expect_pcm
++ - (int)*data_pcm
++);
911 return diff
* 100 / 65536 / size
;
914 static DWORD
compare_bytes(const BYTE
*data
, DWORD
*length
, const RECT
*rect
, const BYTE
*expect
)
916 DWORD i
, size
= *length
, diff
= 0;
918 for (i
= 0; i
< size
; i
++)
919 diff
+= abs((int)*expect
++ - (int)*data
++);
921 return diff
* 100 / 256 / size
;
924 static void dump_rgb(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
, UINT bits
)
926 DWORD width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
927 static const char magic
[2] = "BM";
933 BITMAPINFOHEADER biHeader
;
936 .length
= length
+ sizeof(header
) + 2, .offset
= sizeof(header
) + 2,
939 .biSize
= sizeof(BITMAPINFOHEADER
), .biWidth
= width
, .biHeight
= height
, .biPlanes
= 1,
940 .biBitCount
= bits
, .biCompression
= BI_RGB
, .biSizeImage
= width
* height
* (bits
/ 8),
946 ret
= WriteFile(output
, magic
, sizeof(magic
), &written
, NULL
);
947 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
948 ok(written
== sizeof(magic
), "written %lu bytes\n", written
);
949 ret
= WriteFile(output
, &header
, sizeof(header
), &written
, NULL
);
950 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
951 ok(written
== sizeof(header
), "written %lu bytes\n", written
);
952 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
953 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
954 ok(written
== length
, "written %lu bytes\n", written
);
957 void dump_rgb32(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
959 return dump_rgb(data
, length
, rect
, output
, 32);
962 void dump_rgb24(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
964 return dump_rgb(data
, length
, rect
, output
, 24);
967 void dump_rgb16(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
969 return dump_rgb(data
, length
, rect
, output
, 16);
972 void dump_nv12(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
974 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
975 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
978 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
980 *rgb32
++ = data
[width
* y
+ x
];
981 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 0];
982 *rgb32
++ = data
[width
* height
+ width
* (y
/ 2) + (x
& ~1) + 1];
986 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
989 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
990 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
991 ok(written
== length
, "written %lu bytes\n", written
);
994 void dump_i420(const BYTE
*data
, DWORD length
, const RECT
*rect
, HANDLE output
)
996 DWORD written
, x
, y
, width
= (rect
->right
+ 0xf) & ~0xf, height
= (rect
->bottom
+ 0xf) & ~0xf;
997 BYTE
*rgb32_data
= malloc(width
* height
* 4), *rgb32
= rgb32_data
;
1000 for (y
= 0; y
< height
; y
++) for (x
= 0; x
< width
; x
++)
1002 *rgb32
++ = data
[width
* y
+ x
];
1003 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + x
/ 2];
1004 *rgb32
++ = data
[width
* height
+ (width
/ 2) * (y
/ 2) + (width
/ 2) * (height
/ 2) + x
/ 2];
1008 dump_rgb32(rgb32_data
, width
* height
* 4, rect
, output
);
1011 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
1012 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
1013 ok(written
== length
, "written %lu bytes\n", written
);
1016 typedef void (*enum_mf_media_buffers_cb
)(IMFMediaBuffer
*buffer
, const struct buffer_desc
*desc
, void *context
);
1017 static void enum_mf_media_buffers(IMFSample
*sample
, const struct sample_desc
*sample_desc
,
1018 enum_mf_media_buffers_cb callback
, void *context
)
1020 IMFMediaBuffer
*buffer
;
1024 for (i
= 0; SUCCEEDED(hr
= IMFSample_GetBufferByIndex(sample
, i
, &buffer
)); i
++)
1026 winetest_push_context("buffer %lu", i
);
1027 ok(hr
== S_OK
, "GetBufferByIndex returned %#lx\n", hr
);
1028 ok(i
< sample_desc
->buffer_count
, "got unexpected buffer\n");
1030 callback(buffer
, sample_desc
->buffers
+ i
, context
);
1032 IMFMediaBuffer_Release(buffer
);
1033 winetest_pop_context();
1035 ok(hr
== E_INVALIDARG
, "GetBufferByIndex returned %#lx\n", hr
);
1038 struct enum_mf_sample_state
1040 const struct sample_desc
*next_sample
;
1041 struct sample_desc sample
;
1044 typedef void (*enum_mf_sample_cb
)(IMFSample
*sample
, const struct sample_desc
*sample_desc
, void *context
);
1045 static void enum_mf_samples(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
1046 enum_mf_sample_cb callback
, void *context
)
1048 struct enum_mf_sample_state state
= {.next_sample
= collection_desc
};
1053 for (i
= 0; SUCCEEDED(hr
= IMFCollection_GetElement(samples
, i
, (IUnknown
**)&sample
)); i
++)
1055 winetest_push_context("sample %lu", i
);
1056 ok(hr
== S_OK
, "GetElement returned %#lx\n", hr
);
1058 state
.sample
.sample_time
+= state
.sample
.sample_duration
;
1059 if (!state
.sample
.repeat_count
--)
1060 state
.sample
= *state
.next_sample
++;
1062 callback(sample
, &state
.sample
, context
);
1064 IMFSample_Release(sample
);
1065 winetest_pop_context();
1067 ok(hr
== E_INVALIDARG
, "GetElement returned %#lx\n", hr
);
1070 static void dump_mf_media_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*buffer_desc
, HANDLE output
)
1072 DWORD length
, written
;
1077 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
1078 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
1080 if (buffer_desc
->dump
)
1081 buffer_desc
->dump(data
, length
, &buffer_desc
->rect
, output
);
1084 if (buffer_desc
->length
== -1)
1086 ret
= WriteFile(output
, &length
, sizeof(length
), &written
, NULL
);
1087 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
1088 ok(written
== sizeof(length
), "written %lu bytes\n", written
);
1091 ret
= WriteFile(output
, data
, length
, &written
, NULL
);
1092 ok(ret
, "WriteFile failed, error %lu\n", GetLastError());
1093 ok(written
== length
, "written %lu bytes\n", written
);
1096 hr
= IMFMediaBuffer_Unlock(buffer
);
1097 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
1100 static void dump_mf_sample(IMFSample
*sample
, const struct sample_desc
*sample_desc
, HANDLE output
)
1102 enum_mf_media_buffers(sample
, sample_desc
, dump_mf_media_buffer
, output
);
1105 static void dump_mf_sample_collection(IMFCollection
*samples
, const struct sample_desc
*collection_desc
,
1106 const WCHAR
*output_filename
)
1108 WCHAR path
[MAX_PATH
];
1111 GetTempPathW(ARRAY_SIZE(path
), path
);
1112 lstrcatW(path
, output_filename
);
1114 output
= CreateFileW(path
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, 0, 0);
1115 ok(output
!= INVALID_HANDLE_VALUE
, "CreateFileW failed, error %lu\n", GetLastError());
1117 enum_mf_samples(samples
, collection_desc
, dump_mf_sample
, output
);
1119 trace("created %s\n", debugstr_w(path
));
1120 CloseHandle(output
);
1123 #define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__FILE__, __LINE__, a, b, c)
1124 static DWORD
check_mf_media_buffer_(const char *file
, int line
, IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
,
1125 const BYTE
**expect_data
, DWORD
*expect_data_len
)
1127 DWORD length
, diff
= 0, expect_length
= expect
->length
;
1131 if (expect_length
== -1)
1133 expect_length
= *(DWORD
*)*expect_data
;
1134 *expect_data
= *expect_data
+ sizeof(DWORD
);
1135 *expect_data_len
= *expect_data_len
- sizeof(DWORD
);
1138 hr
= IMFMediaBuffer_Lock(buffer
, &data
, NULL
, &length
);
1139 ok_(file
, line
)(hr
== S_OK
, "Lock returned %#lx\n", hr
);
1140 todo_wine_if(expect
->todo_length
)
1141 ok_(file
, line
)(length
== expect_length
, "got length %#lx\n", length
);
1145 if (*expect_data_len
< length
)
1146 todo_wine_if(expect
->todo_length
)
1147 ok_(file
, line
)(0, "missing %#lx bytes\n", length
- *expect_data_len
);
1148 else if (!expect
->compare
)
1149 diff
= compare_bytes(data
, &length
, NULL
, *expect_data
);
1151 diff
= expect
->compare(data
, &length
, &expect
->rect
, *expect_data
);
1154 hr
= IMFMediaBuffer_Unlock(buffer
);
1155 ok_(file
, line
)(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
1157 *expect_data
= *expect_data
+ min(length
, *expect_data_len
);
1158 *expect_data_len
= *expect_data_len
- min(length
, *expect_data_len
);
1163 struct check_mf_sample_context
1173 static void check_mf_sample_buffer(IMFMediaBuffer
*buffer
, const struct buffer_desc
*expect
, void *context
)
1175 struct check_mf_sample_context
*ctx
= context
;
1176 DWORD expect_length
= expect
->length
== -1 ? *(DWORD
*)ctx
->data
: expect
->length
;
1177 ctx
->diff
+= check_mf_media_buffer_(ctx
->file
, ctx
->line
, buffer
, expect
, &ctx
->data
, &ctx
->data_len
);
1178 ctx
->total_length
+= expect_length
;
1181 #define check_mf_sample(a, b, c, d) check_mf_sample_(__FILE__, __LINE__, a, b, c, d)
1182 static DWORD
check_mf_sample_(const char *file
, int line
, IMFSample
*sample
, const struct sample_desc
*expect
,
1183 const BYTE
**expect_data
, DWORD
*expect_data_len
)
1185 struct check_mf_sample_context ctx
= {.data
= *expect_data
, .data_len
= *expect_data_len
, .file
= file
, .line
= line
};
1186 DWORD buffer_count
, total_length
, sample_flags
;
1190 if (expect
->attributes
)
1191 check_attributes_(file
, line
, (IMFAttributes
*)sample
, expect
->attributes
, -1);
1193 buffer_count
= 0xdeadbeef;
1194 hr
= IMFSample_GetBufferCount(sample
, &buffer_count
);
1195 ok_(file
, line
)(hr
== S_OK
, "GetBufferCount returned %#lx\n", hr
);
1196 ok_(file
, line
)(buffer_count
== expect
->buffer_count
,
1197 "got %lu buffers\n", buffer_count
);
1199 sample_flags
= 0xdeadbeef;
1200 hr
= IMFSample_GetSampleFlags(sample
, &sample_flags
);
1201 ok_(file
, line
)(hr
== S_OK
, "GetSampleFlags returned %#lx\n", hr
);
1202 ok_(file
, line
)(sample_flags
== 0,
1203 "got sample flags %#lx\n", sample_flags
);
1205 timestamp
= 0xdeadbeef;
1206 hr
= IMFSample_GetSampleTime(sample
, ×tamp
);
1207 ok_(file
, line
)(hr
== S_OK
, "GetSampleTime returned %#lx\n", hr
);
1208 todo_wine_if(expect
->todo_time
)
1209 ok_(file
, line
)(llabs(timestamp
- expect
->sample_time
) <= 50,
1210 "got sample time %I64d\n", timestamp
);
1212 timestamp
= 0xdeadbeef;
1213 hr
= IMFSample_GetSampleDuration(sample
, ×tamp
);
1214 ok_(file
, line
)(hr
== S_OK
, "GetSampleDuration returned %#lx\n", hr
);
1215 todo_wine_if(expect
->todo_duration
&& expect
->todo_duration
== timestamp
)
1216 ok_(file
, line
)(llabs(timestamp
- expect
->sample_duration
) <= 1,
1217 "got sample duration %I64d\n", timestamp
);
1219 enum_mf_media_buffers(sample
, expect
, check_mf_sample_buffer
, &ctx
);
1221 total_length
= 0xdeadbeef;
1222 hr
= IMFSample_GetTotalLength(sample
, &total_length
);
1223 ok_(file
, line
)(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
1224 todo_wine_if(expect
->todo_length
)
1225 ok_(file
, line
)(total_length
== ctx
.total_length
,
1226 "got total length %#lx\n", total_length
);
1227 ok_(file
, line
)(!*expect_data
|| *expect_data_len
>= ctx
.total_length
,
1228 "missing %#lx data\n", ctx
.total_length
- *expect_data_len
);
1230 *expect_data
= ctx
.data
;
1231 *expect_data_len
= ctx
.data_len
;
1233 return ctx
.diff
/ buffer_count
;
1236 static void check_mf_sample_collection_enum(IMFSample
*sample
, const struct sample_desc
*expect
, void *context
)
1238 struct check_mf_sample_context
*ctx
= context
;
1239 ctx
->diff
+= check_mf_sample_(ctx
->file
, ctx
->line
, sample
, expect
, &ctx
->data
, &ctx
->data_len
);
1242 DWORD
check_mf_sample_collection_(const char *file
, int line
, IMFCollection
*samples
,
1243 const struct sample_desc
*expect_samples
, const WCHAR
*expect_data_filename
)
1245 struct check_mf_sample_context ctx
= {.file
= file
, .line
= line
};
1249 if (expect_data_filename
) load_resource(expect_data_filename
, &ctx
.data
, &ctx
.data_len
);
1250 enum_mf_samples(samples
, expect_samples
, check_mf_sample_collection_enum
, &ctx
);
1252 if (expect_data_filename
) dump_mf_sample_collection(samples
, expect_samples
, expect_data_filename
);
1254 hr
= IMFCollection_GetElementCount(samples
, &count
);
1255 ok_(file
, line
)(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
1257 return ctx
.diff
/ count
;
1260 #define check_video_info_header(a, b) check_video_info_header_(__LINE__, a, b)
1261 static void check_video_info_header_(int line
, VIDEOINFOHEADER
*info
, const VIDEOINFOHEADER
*expected
)
1263 ok_(__FILE__
, line
)(info
->rcSource
.left
== expected
->rcSource
.left
1264 && info
->rcSource
.top
== expected
->rcSource
.top
1265 && info
->rcSource
.right
== expected
->rcSource
.right
1266 && info
->rcSource
.bottom
== expected
->rcSource
.bottom
,
1267 "Got unexpected rcSource {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1268 info
->rcSource
.left
, info
->rcSource
.top
, info
->rcSource
.right
, info
->rcSource
.bottom
,
1269 expected
->rcSource
.left
, expected
->rcSource
.top
, expected
->rcSource
.right
, expected
->rcSource
.bottom
);
1270 ok_(__FILE__
, line
)(info
->rcTarget
.left
== expected
->rcTarget
.left
1271 && info
->rcTarget
.top
== expected
->rcTarget
.top
1272 && info
->rcTarget
.right
== expected
->rcTarget
.right
1273 && info
->rcTarget
.bottom
== expected
->rcTarget
.bottom
,
1274 "Got unexpected rcTarget {%ld, %ld, %ld, %ld}, expected {%ld, %ld, %ld, %ld}.\n",
1275 info
->rcTarget
.left
, info
->rcTarget
.top
, info
->rcTarget
.right
, info
->rcTarget
.bottom
,
1276 expected
->rcTarget
.left
, expected
->rcTarget
.top
, expected
->rcTarget
.right
, expected
->rcTarget
.bottom
);
1277 ok_(__FILE__
, line
)(info
->dwBitRate
== expected
->dwBitRate
,
1278 "Got unexpected dwBitRate %lu, expected %lu.\n",
1279 info
->dwBitRate
, expected
->dwBitRate
);
1280 ok_(__FILE__
, line
)(info
->dwBitErrorRate
== expected
->dwBitErrorRate
,
1281 "Got unexpected dwBitErrorRate %lu, expected %lu.\n",
1282 info
->dwBitErrorRate
, expected
->dwBitErrorRate
);
1283 ok_(__FILE__
, line
)(info
->AvgTimePerFrame
== expected
->AvgTimePerFrame
,
1284 "Got unexpected AvgTimePerFrame %I64d, expected %I64d.\n",
1285 info
->AvgTimePerFrame
, expected
->AvgTimePerFrame
);
1286 ok_(__FILE__
, line
)(info
->bmiHeader
.biSize
== expected
->bmiHeader
.biSize
,
1287 "Got unexpected bmiHeader.biSize %lu, expected %lu.\n",
1288 info
->bmiHeader
.biSize
, expected
->bmiHeader
.biSize
);
1289 ok_(__FILE__
, line
)(info
->bmiHeader
.biWidth
== expected
->bmiHeader
.biWidth
,
1290 "Got unexpected bmiHeader.biWidth %ld, expected %ld.\n",
1291 info
->bmiHeader
.biWidth
, expected
->bmiHeader
.biWidth
);
1292 ok_(__FILE__
, line
)(info
->bmiHeader
.biHeight
== expected
->bmiHeader
.biHeight
,
1293 "Got unexpected bmiHeader.biHeight %ld, expected %ld.\n",
1294 info
->bmiHeader
.biHeight
, expected
->bmiHeader
.biHeight
);
1295 ok_(__FILE__
, line
)(info
->bmiHeader
.biPlanes
== expected
->bmiHeader
.biPlanes
,
1296 "Got unexpected bmiHeader.biPlanes %u, expected %u.\n",
1297 info
->bmiHeader
.biPlanes
, expected
->bmiHeader
.biPlanes
);
1298 ok_(__FILE__
, line
)(info
->bmiHeader
.biBitCount
== expected
->bmiHeader
.biBitCount
,
1299 "Got unexpected bmiHeader.biBitCount %u, expected %u.\n",
1300 info
->bmiHeader
.biBitCount
, expected
->bmiHeader
.biBitCount
);
1301 ok_(__FILE__
, line
)(info
->bmiHeader
.biCompression
== expected
->bmiHeader
.biCompression
,
1302 "Got unexpected bmiHeader.biCompression %#lx, expected %#lx.\n",
1303 info
->bmiHeader
.biCompression
, expected
->bmiHeader
.biCompression
);
1304 ok_(__FILE__
, line
)(info
->bmiHeader
.biSizeImage
== expected
->bmiHeader
.biSizeImage
,
1305 "Got unexpected bmiHeader.biSizeImage %lu, expected %lu.\n",
1306 info
->bmiHeader
.biSizeImage
, expected
->bmiHeader
.biSizeImage
);
1307 ok_(__FILE__
, line
)(info
->bmiHeader
.biXPelsPerMeter
== expected
->bmiHeader
.biXPelsPerMeter
,
1308 "Got unexpected bmiHeader.biXPelsPerMeter %ld, expected %ld.\n",
1309 info
->bmiHeader
.biXPelsPerMeter
, expected
->bmiHeader
.biXPelsPerMeter
);
1310 ok_(__FILE__
, line
)(info
->bmiHeader
.biYPelsPerMeter
== expected
->bmiHeader
.biYPelsPerMeter
,
1311 "Got unexpected bmiHeader.xxxxxx %ld, expected %ld.\n",
1312 info
->bmiHeader
.biYPelsPerMeter
, expected
->bmiHeader
.biYPelsPerMeter
);
1313 todo_wine_if(expected
->bmiHeader
.biClrUsed
!= 0)
1314 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrUsed
== expected
->bmiHeader
.biClrUsed
,
1315 "Got unexpected bmiHeader.biClrUsed %lu, expected %lu.\n",
1316 info
->bmiHeader
.biClrUsed
, expected
->bmiHeader
.biClrUsed
);
1317 todo_wine_if(expected
->bmiHeader
.biClrImportant
!= 0)
1318 ok_(__FILE__
, line
)(info
->bmiHeader
.biClrImportant
== expected
->bmiHeader
.biClrImportant
,
1319 "Got unexpected bmiHeader.biClrImportant %lu, expected %lu.\n",
1320 info
->bmiHeader
.biClrImportant
, expected
->bmiHeader
.biClrImportant
);
1323 #define check_dmo_media_type(a, b) check_dmo_media_type_(__LINE__, a, b)
1324 static void check_dmo_media_type_(int line
, DMO_MEDIA_TYPE
*media_type
, const DMO_MEDIA_TYPE
*expected
)
1326 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->majortype
, &expected
->majortype
),
1327 "Got unexpected majortype %s, expected %s.\n",
1328 debugstr_guid(&media_type
->majortype
), debugstr_guid(&expected
->majortype
));
1329 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->subtype
, &expected
->subtype
),
1330 "Got unexpected subtype %s, expected %s.\n",
1331 debugstr_guid(&media_type
->subtype
), debugstr_guid(&expected
->subtype
));
1332 ok_(__FILE__
, line
)(media_type
->bFixedSizeSamples
== expected
->bFixedSizeSamples
,
1333 "Got unexpected bFixedSizeSamples %d, expected %d.\n",
1334 media_type
->bFixedSizeSamples
, expected
->bFixedSizeSamples
);
1335 ok_(__FILE__
, line
)(media_type
->bTemporalCompression
== expected
->bTemporalCompression
,
1336 "Got unexpected bTemporalCompression %d, expected %d.\n",
1337 media_type
->bTemporalCompression
, expected
->bTemporalCompression
);
1338 ok_(__FILE__
, line
)(media_type
->lSampleSize
== expected
->lSampleSize
,
1339 "Got unexpected lSampleSize %lu, expected %lu.\n",
1340 media_type
->lSampleSize
, expected
->lSampleSize
);
1341 ok_(__FILE__
, line
)(IsEqualGUID(&media_type
->formattype
, &expected
->formattype
),
1342 "Got unexpected formattype %s.\n",
1343 debugstr_guid(&media_type
->formattype
));
1344 ok_(__FILE__
, line
)(media_type
->pUnk
== NULL
, "Got unexpected pUnk %p.\n", media_type
->pUnk
);
1345 todo_wine_if(expected
->cbFormat
&& expected
->cbFormat
!= sizeof(VIDEOINFOHEADER
))
1346 ok_(__FILE__
, line
)(media_type
->cbFormat
== expected
->cbFormat
,
1347 "Got unexpected cbFormat %lu, expected %lu.\n",
1348 media_type
->cbFormat
, expected
->cbFormat
);
1350 if (expected
->pbFormat
)
1352 ok_(__FILE__
, line
)(!!media_type
->pbFormat
, "Got NULL pbFormat.\n");
1353 if (!media_type
->pbFormat
)
1356 if (IsEqualGUID(&media_type
->formattype
, &FORMAT_VideoInfo
)
1357 && IsEqualGUID(&expected
->formattype
, &FORMAT_VideoInfo
))
1358 check_video_info_header((VIDEOINFOHEADER
*)media_type
->pbFormat
, (VIDEOINFOHEADER
*)expected
->pbFormat
);
1362 static void check_dmo_get_input_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1364 DMO_MEDIA_TYPE media_type
;
1368 hr
= IMediaObject_GetInputType(media_object
, 1, 0, NULL
);
1369 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1370 hr
= IMediaObject_GetInputType(media_object
, 1, 0, &media_type
);
1371 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1372 hr
= IMediaObject_GetInputType(media_object
, 1, count
, &media_type
);
1373 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputType returned %#lx.\n", hr
);
1374 hr
= IMediaObject_GetInputType(media_object
, 0, count
, &media_type
);
1375 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1376 hr
= IMediaObject_GetInputType(media_object
, 0, count
, NULL
);
1377 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1378 hr
= IMediaObject_GetInputType(media_object
, 0, 0xdeadbeef, NULL
);
1379 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1380 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, NULL
);
1381 ok(hr
== S_OK
, "GetInputType returned %#lx.\n", hr
);
1382 hr
= IMediaObject_GetInputType(media_object
, 0, count
- 1, &media_type
);
1383 ok(hr
== S_OK
, "GetInputType returned %#lx.\n", hr
);
1385 MoFreeMediaType(&media_type
);
1388 while (SUCCEEDED(hr
= IMediaObject_GetInputType(media_object
, 0, ++i
, &media_type
)))
1390 winetest_push_context("in %lu", i
);
1391 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1392 MoFreeMediaType(&media_type
);
1393 winetest_pop_context();
1396 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetInputType returned %#lx.\n", hr
);
1397 ok(i
== count
, "%lu types.\n", i
);
1400 static void check_dmo_get_output_type(IMediaObject
*media_object
, const DMO_MEDIA_TYPE
*expected_type
, ULONG count
)
1402 DMO_MEDIA_TYPE media_type
;
1406 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, NULL
);
1407 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1408 hr
= IMediaObject_GetOutputType(media_object
, 1, 0, &media_type
);
1409 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1410 hr
= IMediaObject_GetOutputType(media_object
, 1, count
, &media_type
);
1411 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetOutputType returned %#lx.\n", hr
);
1412 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, &media_type
);
1413 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned %#lx.\n", hr
);
1414 hr
= IMediaObject_GetOutputType(media_object
, 0, count
, NULL
);
1415 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned %#lx.\n", hr
);
1416 hr
= IMediaObject_GetOutputType(media_object
, 0, 0xdeadbeef, NULL
);
1417 ok(hr
== DMO_E_NO_MORE_ITEMS
|| broken(hr
== S_OK
), "GetOutputType returned %#lx.\n", hr
);
1418 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, NULL
);
1419 ok(hr
== S_OK
, "GetOutputType returned %#lx.\n", hr
);
1420 hr
= IMediaObject_GetOutputType(media_object
, 0, count
- 1, &media_type
);
1421 ok(hr
== S_OK
, "GetOutputType returned %#lx.\n", hr
);
1423 MoFreeMediaType(&media_type
);
1426 while (SUCCEEDED(hr
= IMediaObject_GetOutputType(media_object
, 0, ++i
, &media_type
)))
1428 winetest_push_context("out %lu", i
);
1429 check_dmo_media_type(&media_type
, &expected_type
[i
]);
1430 MoFreeMediaType(&media_type
);
1431 winetest_pop_context();
1434 ok(hr
== DMO_E_NO_MORE_ITEMS
, "GetOutputType returned %#lx.\n", hr
);
1435 ok(i
== count
, "%lu types.\n", i
);
1438 static void check_dmo_set_input_type(IMediaObject
*media_object
, const GUID
*subtype
)
1440 DMO_MEDIA_TYPE bad_media_type
, *good_media_type
;
1441 VIDEOINFOHEADER
*header
;
1446 const DWORD flags
[] = {0, 0x4, DMO_SET_TYPEF_CLEAR
, DMO_SET_TYPEF_TEST_ONLY
, DMO_SET_TYPEF_TEST_ONLY
| 0x4};
1448 memset(&bad_media_type
, 0, sizeof(bad_media_type
));
1449 good_media_type
= (DMO_MEDIA_TYPE
*)buffer
;
1450 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1451 header
= (VIDEOINFOHEADER
*)(good_media_type
+ 1);
1453 /* Test invalid stream index. */
1454 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1457 hr
= IMediaObject_SetInputType(media_object
, 1, NULL
, flag
);
1458 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1459 hr
= IMediaObject_SetInputType(media_object
, 1, &bad_media_type
, flag
);
1460 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1461 hr
= IMediaObject_SetInputType(media_object
, 1, good_media_type
, flag
);
1462 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1465 /* Test unaccepted type. */
1466 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1469 if (!(flag
& DMO_SET_TYPEF_CLEAR
))
1471 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, flag
);
1472 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1474 hr
= IMediaObject_SetInputType(media_object
, 0, &bad_media_type
, flag
);
1475 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1478 /* Test clearing the type. */
1479 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1481 flag
= DMO_SET_TYPEF_CLEAR
| flags
[i
];
1482 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, flag
);
1483 ok(hr
== S_OK
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1486 /* Test accepted type. */
1487 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1490 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, flag
);
1491 ok(hr
== S_OK
, "SetInputType returned %#lx for flag %#lx.\n", hr
, flag
);
1494 /* Test unconsidered header member.*/
1495 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1496 header
->dwBitRate
= 0xdeadbeef;
1497 header
->dwBitErrorRate
= 0xdeadbeef;
1498 header
->AvgTimePerFrame
= 0xdeadbeef;
1499 header
->bmiHeader
.biPlanes
= 0xdead;
1500 header
->bmiHeader
.biBitCount
= 0xdead;
1501 header
->bmiHeader
.biSizeImage
= 0xdeadbeef;
1502 header
->bmiHeader
.biXPelsPerMeter
= 0xdead;
1503 header
->bmiHeader
.biYPelsPerMeter
= 0xdead;
1504 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, 0);
1505 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1507 /* Test invalid major type. */
1508 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1509 good_media_type
->majortype
= MFMediaType_Default
;
1510 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1511 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1513 /* Test invalid subtype. */
1514 init_dmo_media_type_video(good_media_type
, &MEDIASUBTYPE_None
, 16, 16);
1515 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1516 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1518 /* Test invalid format type. */
1519 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1520 good_media_type
->formattype
= FORMAT_None
;
1521 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1522 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1524 /* Test invalid format size. */
1525 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1526 good_media_type
->cbFormat
= 1;
1527 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1528 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1530 /* Test NULL format pointer. */
1531 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1532 good_media_type
->pbFormat
= NULL
;
1533 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1534 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1536 /* Test video header struct size. */
1537 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1538 header
->bmiHeader
.biSize
= 0;
1539 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1541 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1542 header
->bmiHeader
.biSize
= 1;
1543 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1545 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1546 header
->bmiHeader
.biSize
= 0xdeadbeef;
1547 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1549 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1552 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1553 header
->bmiHeader
.biWidth
= 0;
1554 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1556 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1557 header
->bmiHeader
.biWidth
= -1;
1558 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1560 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1561 header
->bmiHeader
.biWidth
= 4096 + 1;
1562 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1564 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1565 header
->bmiHeader
.biWidth
= 4096;
1566 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1567 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1570 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1571 header
->bmiHeader
.biHeight
= 0;
1572 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1574 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1575 header
->bmiHeader
.biHeight
= 4096 + 1;
1576 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1578 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1579 header
->bmiHeader
.biHeight
= 4096;
1580 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1581 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1582 header
->bmiHeader
.biHeight
= -4096;
1583 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1584 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1586 /* Test compression. */
1587 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1588 header
->bmiHeader
.biCompression
= 0;
1589 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1591 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetInputType returned %#lx.\n", hr
);
1592 header
->bmiHeader
.biCompression
= 1;
1593 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1594 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1595 header
->bmiHeader
.biCompression
= 2;
1596 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1597 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1598 header
->bmiHeader
.biCompression
= 0xdeadbeef;
1599 hr
= IMediaObject_SetInputType(media_object
, 0, good_media_type
, DMO_SET_TYPEF_TEST_ONLY
);
1600 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
1603 static void check_dmo_set_output_type(IMediaObject
*media_object
, const GUID
*subtype
)
1605 DMO_MEDIA_TYPE bad_media_type
, *good_media_type
;
1610 const DWORD flags
[] = {0, 0x4, DMO_SET_TYPEF_CLEAR
, DMO_SET_TYPEF_TEST_ONLY
, DMO_SET_TYPEF_TEST_ONLY
| 0x4};
1612 memset(&bad_media_type
, 0, sizeof(bad_media_type
));
1613 good_media_type
= (DMO_MEDIA_TYPE
*)buffer
;
1614 init_dmo_media_type_video(good_media_type
, subtype
, 16, 16);
1616 /* Test invalid stream index. */
1617 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1620 hr
= IMediaObject_SetOutputType(media_object
, 1, NULL
, flag
);
1621 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1622 hr
= IMediaObject_SetOutputType(media_object
, 1, &bad_media_type
, flag
);
1623 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1624 hr
= IMediaObject_SetOutputType(media_object
, 1, good_media_type
, flag
);
1625 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1628 /* Test unaccepted type. */
1629 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1632 if (!(flag
& DMO_SET_TYPEF_CLEAR
))
1634 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, flag
);
1635 ok(hr
== E_POINTER
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1637 hr
= IMediaObject_SetOutputType(media_object
, 0, &bad_media_type
, flag
);
1638 ok(hr
== DMO_E_TYPE_NOT_ACCEPTED
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1641 /* Test clearing the type. */
1642 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1644 flag
= DMO_SET_TYPEF_CLEAR
| flags
[i
];
1645 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, flag
);
1646 ok(hr
== S_OK
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1649 /* Test accepted type. */
1650 for (i
= 0; i
< ARRAY_SIZE(flags
); ++i
)
1653 hr
= IMediaObject_SetOutputType(media_object
, 0, good_media_type
, flag
);
1654 ok(hr
== S_OK
, "SetOutputType returned %#lx for flag %#lx.\n", hr
, flag
);
1658 #define check_dmo_output_data_buffer(a, b, c, d, e) check_dmo_output_data_buffer_(__LINE__, a, b, c, d, e)
1659 static DWORD
check_dmo_output_data_buffer_(int line
, DMO_OUTPUT_DATA_BUFFER
*output_data_buffer
,
1660 const struct buffer_desc
*buffer_desc
, const WCHAR
*expect_data_filename
,
1661 REFERENCE_TIME time_stamp
, REFERENCE_TIME time_length
)
1663 DWORD diff
, data_length
, buffer_length
, expect_length
;
1664 BYTE
*data
, *buffer
;
1667 if (output_data_buffer
->dwStatus
& DMO_OUTPUT_DATA_BUFFERF_TIME
)
1668 ok_(__FILE__
, line
)(output_data_buffer
->rtTimestamp
== time_stamp
,
1669 "Unexpected time stamp %I64d, expected %I64d.\n",
1670 output_data_buffer
->rtTimestamp
, time_stamp
);
1671 if (output_data_buffer
->dwStatus
& DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH
)
1673 ok_(__FILE__
, line
)(output_data_buffer
->rtTimelength
== time_length
,
1674 "Unexpected time length %I64d, expected %I64d.\n",
1675 output_data_buffer
->rtTimelength
, time_length
);
1677 load_resource(expect_data_filename
, (const BYTE
**)&data
, &data_length
);
1679 expect_length
= buffer_desc
->length
;
1680 if (expect_length
== -1)
1682 expect_length
= *(DWORD
*)data
;
1683 data
+= sizeof(DWORD
);
1684 data_length
= data_length
- sizeof(DWORD
);
1687 hr
= IMediaBuffer_GetBufferAndLength(output_data_buffer
->pBuffer
, &buffer
, &buffer_length
);
1688 ok(hr
== S_OK
, "GetBufferAndLength returned %#lx.\n", hr
);
1689 ok_(__FILE__
, line
)(buffer_length
== expect_length
, "Unexpected length %#lx, expected %#lx\n", buffer_length
, expect_length
);
1692 if (data_length
< buffer_length
)
1693 ok_(__FILE__
, line
)(0, "Missing %#lx bytes\n", buffer_length
- data_length
);
1694 else if (!buffer_desc
->compare
)
1695 diff
= compare_bytes(buffer
, &buffer_length
, NULL
, data
);
1697 diff
= buffer_desc
->compare(buffer
, &buffer_length
, &buffer_desc
->rect
, data
);
1703 static HRESULT WINAPI
test_unk_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
1705 if (IsEqualIID(riid
, &IID_IUnknown
))
1708 IUnknown_AddRef(iface
);
1713 return E_NOINTERFACE
;
1716 static ULONG WINAPI
test_unk_AddRef(IUnknown
*iface
)
1721 static ULONG WINAPI
test_unk_Release(IUnknown
*iface
)
1726 static const IUnknownVtbl test_unk_vtbl
=
1728 test_unk_QueryInterface
,
1733 static BOOL
is_supported_video_type(const GUID
*guid
)
1735 return IsEqualGUID(guid
, &MFVideoFormat_L8
)
1736 || IsEqualGUID(guid
, &MFVideoFormat_L16
)
1737 || IsEqualGUID(guid
, &MFVideoFormat_D16
)
1738 || IsEqualGUID(guid
, &MFVideoFormat_IYUV
)
1739 || IsEqualGUID(guid
, &MFVideoFormat_YV12
)
1740 || IsEqualGUID(guid
, &MFVideoFormat_NV12
)
1741 || IsEqualGUID(guid
, &MFVideoFormat_NV21
)
1742 || IsEqualGUID(guid
, &MFVideoFormat_420O
)
1743 || IsEqualGUID(guid
, &MFVideoFormat_P010
)
1744 || IsEqualGUID(guid
, &MFVideoFormat_P016
)
1745 || IsEqualGUID(guid
, &MFVideoFormat_UYVY
)
1746 || IsEqualGUID(guid
, &MFVideoFormat_YUY2
)
1747 || IsEqualGUID(guid
, &MFVideoFormat_P208
)
1748 || IsEqualGUID(guid
, &MFVideoFormat_NV11
)
1749 || IsEqualGUID(guid
, &MFVideoFormat_AYUV
)
1750 || IsEqualGUID(guid
, &MFVideoFormat_ARGB32
)
1751 || IsEqualGUID(guid
, &MFVideoFormat_RGB32
)
1752 || IsEqualGUID(guid
, &MFVideoFormat_A2R10G10B10
)
1753 || IsEqualGUID(guid
, &MFVideoFormat_A16B16G16R16F
)
1754 || IsEqualGUID(guid
, &MFVideoFormat_RGB24
)
1755 || IsEqualGUID(guid
, &MFVideoFormat_I420
)
1756 || IsEqualGUID(guid
, &MFVideoFormat_YVYU
)
1757 || IsEqualGUID(guid
, &MFVideoFormat_RGB555
)
1758 || IsEqualGUID(guid
, &MFVideoFormat_RGB565
)
1759 || IsEqualGUID(guid
, &MFVideoFormat_RGB8
)
1760 || IsEqualGUID(guid
, &MFVideoFormat_Y216
)
1761 || IsEqualGUID(guid
, &MFVideoFormat_v410
)
1762 || IsEqualGUID(guid
, &MFVideoFormat_Y41P
)
1763 || IsEqualGUID(guid
, &MFVideoFormat_Y41T
)
1764 || IsEqualGUID(guid
, &MFVideoFormat_Y42T
)
1765 || IsEqualGUID(guid
, &MFVideoFormat_ABGR32
);
1768 static BOOL
is_sample_copier_available_type(IMFMediaType
*type
)
1774 hr
= IMFMediaType_GetMajorType(type
, &major
);
1775 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
1777 hr
= IMFMediaType_GetCount(type
, &count
);
1778 ok(hr
== S_OK
, "Failed to get attribute count, hr %#lx.\n", hr
);
1779 ok(count
== 1, "Unexpected attribute count %u.\n", count
);
1781 return IsEqualGUID(&major
, &MFMediaType_Video
) || IsEqualGUID(&major
, &MFMediaType_Audio
);
1784 static void test_sample_copier(void)
1786 static const struct attribute_desc expect_transform_attributes
[] =
1788 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, 1),
1791 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 16 * 16};
1792 const MFT_INPUT_STREAM_INFO initial_input_info
= {0}, input_info
= {.cbSize
= 16 * 16};
1793 IMFMediaType
*mediatype
, *mediatype2
;
1794 IMFSample
*sample
, *client_sample
;
1795 IMFMediaBuffer
*media_buffer
;
1796 MFT_INPUT_STREAM_INFO info
;
1797 DWORD flags
, output_status
;
1798 IMFTransform
*copier
;
1802 if (!pMFCreateSampleCopierMFT
)
1804 win_skip("MFCreateSampleCopierMFT() is not available.\n");
1808 winetest_push_context("copier");
1810 hr
= pMFCreateSampleCopierMFT(&copier
);
1811 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
1813 check_interface(copier
, &IID_IMFTransform
, TRUE
);
1814 check_interface(copier
, &IID_IMediaObject
, FALSE
);
1815 check_interface(copier
, &IID_IPropertyStore
, FALSE
);
1816 check_interface(copier
, &IID_IPropertyBag
, FALSE
);
1818 check_mft_optional_methods(copier
, 1);
1819 check_mft_get_attributes(copier
, expect_transform_attributes
, FALSE
);
1821 /* Available types. */
1822 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 0, &mediatype
);
1823 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1824 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1825 IMFMediaType_Release(mediatype
);
1827 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype
);
1828 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1829 ok(is_sample_copier_available_type(mediatype
), "Unexpected type.\n");
1830 IMFMediaType_Release(mediatype
);
1832 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 2, &mediatype
);
1833 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1835 hr
= IMFTransform_GetInputAvailableType(copier
, 1, 0, &mediatype
);
1836 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1838 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype
);
1839 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
1841 hr
= IMFTransform_GetOutputAvailableType(copier
, 1, 0, &mediatype
);
1842 ok(hr
== MF_E_INVALIDSTREAMNUMBER
, "Unexpected hr %#lx.\n", hr
);
1844 check_mft_get_input_current_type(copier
, NULL
);
1845 check_mft_get_output_current_type(copier
, NULL
);
1847 hr
= MFCreateSample(&sample
);
1848 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1850 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1851 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1853 hr
= MFCreateMediaType(&mediatype
);
1854 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
1856 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1857 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "Unexpected hr %#lx.\n", hr
);
1859 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
1860 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1862 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB8
);
1863 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1865 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
1866 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
1868 check_mft_get_input_stream_info(copier
, S_OK
, &initial_input_info
);
1869 check_mft_get_output_stream_info(copier
, S_OK
, &initial_output_info
);
1871 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1872 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1874 memset(&info
, 0xcd, sizeof(info
));
1875 hr
= IMFTransform_GetInputStreamInfo(copier
, 0, &info
);
1876 ok(hr
== S_OK
, "GetInputStreamInfo returned %#lx\n", hr
);
1877 check_member(info
, initial_input_info
, "%I64d", hnsMaxLatency
);
1878 check_member(info
, initial_input_info
, "%#lx", dwFlags
);
1880 check_member(info
, initial_input_info
, "%#lx", cbSize
);
1881 check_member(info
, initial_input_info
, "%#lx", cbMaxLookahead
);
1882 check_member(info
, initial_input_info
, "%#lx", cbAlignment
);
1883 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1885 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1886 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1887 IMFMediaType_Release(mediatype2
);
1889 check_mft_get_input_current_type(copier
, NULL
);
1891 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1892 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1894 /* Setting input type resets output type. */
1895 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1896 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1897 IMFMediaType_Release(mediatype2
);
1899 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
1900 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
1902 hr
= IMFTransform_GetOutputCurrentType(copier
, 0, &mediatype2
);
1903 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1905 hr
= IMFTransform_GetInputAvailableType(copier
, 0, 1, &mediatype2
);
1906 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1907 ok(is_sample_copier_available_type(mediatype2
), "Unexpected type.\n");
1908 IMFMediaType_Release(mediatype2
);
1910 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1911 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1913 hr
= IMFTransform_GetOutputAvailableType(copier
, 0, 0, &mediatype2
);
1914 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1915 hr
= IMFMediaType_IsEqual(mediatype2
, mediatype
, &flags
);
1916 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
1917 IMFMediaType_Release(mediatype2
);
1919 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1920 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1921 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected flags %#lx.\n", flags
);
1923 hr
= IMFTransform_GetInputCurrentType(copier
, 0, &mediatype2
);
1924 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
1925 IMFMediaType_Release(mediatype2
);
1927 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1928 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
1930 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
1931 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
1933 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1934 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1935 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1937 /* Pushing samples. */
1938 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1939 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1941 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
1942 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1943 IMFMediaBuffer_Release(media_buffer
);
1945 EXPECT_REF(sample
, 1);
1946 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1947 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1948 EXPECT_REF(sample
, 2);
1950 hr
= IMFTransform_GetInputStatus(copier
, 0, &flags
);
1951 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
1952 ok(!flags
, "Unexpected flags %#lx.\n", flags
);
1954 hr
= IMFTransform_GetOutputStatus(copier
, &flags
);
1955 ok(hr
== S_OK
, "Failed to get output status, hr %#lx.\n", hr
);
1956 ok(flags
== MFT_OUTPUT_STATUS_SAMPLE_READY
, "Unexpected flags %#lx.\n", flags
);
1958 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1959 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
1961 check_mft_get_input_stream_info(copier
, S_OK
, &input_info
);
1962 check_mft_get_output_stream_info(copier
, S_OK
, &output_info
);
1964 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &media_buffer
);
1965 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
1967 hr
= MFCreateSample(&client_sample
);
1968 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
1970 hr
= IMFSample_AddBuffer(client_sample
, media_buffer
);
1971 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
1972 IMFMediaBuffer_Release(media_buffer
);
1974 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1975 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
1976 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1977 EXPECT_REF(sample
, 1);
1979 hr
= check_mft_process_output(copier
, client_sample
, &output_status
);
1980 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Failed to get output, hr %#lx.\n", hr
);
1981 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
1984 hr
= IMFTransform_ProcessInput(copier
, 0, sample
, 0);
1985 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
1986 EXPECT_REF(sample
, 2);
1988 hr
= IMFTransform_ProcessMessage(copier
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
1989 ok(hr
== S_OK
, "Failed to flush, hr %#lx.\n", hr
);
1991 ref
= IMFSample_Release(sample
);
1992 ok(ref
== 0, "Release returned %ld\n", ref
);
1993 ref
= IMFSample_Release(client_sample
);
1994 ok(ref
== 0, "Release returned %ld\n", ref
);
1996 ref
= IMFTransform_Release(copier
);
1997 ok(ref
== 0, "Release returned %ld\n", ref
);
1998 ref
= IMFMediaType_Release(mediatype
);
1999 ok(ref
== 0, "Release returned %ld\n", ref
);
2001 winetest_pop_context();
2004 struct sample_metadata
2011 static void sample_copier_process(IMFTransform
*copier
, IMFMediaBuffer
*input_buffer
,
2012 IMFMediaBuffer
*output_buffer
, const struct sample_metadata
*md
)
2014 static const struct sample_metadata zero_md
= { 0, ~0u, ~0u };
2015 IMFSample
*input_sample
, *output_sample
;
2016 DWORD flags
, output_status
;
2021 hr
= MFCreateSample(&input_sample
);
2022 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
2026 hr
= IMFSample_SetSampleFlags(input_sample
, md
->flags
);
2027 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2029 hr
= IMFSample_SetSampleTime(input_sample
, md
->time
);
2030 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2032 hr
= IMFSample_SetSampleDuration(input_sample
, md
->duration
);
2033 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2036 hr
= MFCreateSample(&output_sample
);
2037 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
2039 hr
= IMFSample_SetSampleFlags(output_sample
, ~0u);
2040 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2042 hr
= IMFSample_SetSampleTime(output_sample
, ~0u);
2043 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2045 hr
= IMFSample_SetSampleDuration(output_sample
, ~0u);
2046 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2048 hr
= IMFSample_AddBuffer(input_sample
, input_buffer
);
2049 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2051 hr
= IMFSample_AddBuffer(output_sample
, output_buffer
);
2052 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2054 hr
= IMFTransform_ProcessInput(copier
, 0, input_sample
, 0);
2055 ok(hr
== S_OK
, "Failed to process input, hr %#lx.\n", hr
);
2057 hr
= check_mft_process_output(copier
, output_sample
, &output_status
);
2058 ok(hr
== S_OK
, "Failed to get output, hr %#lx.\n", hr
);
2059 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2061 if (!md
) md
= &zero_md
;
2063 hr
= IMFSample_GetSampleFlags(output_sample
, &flags
);
2064 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2065 ok(md
->flags
== flags
, "Unexpected flags.\n");
2066 hr
= IMFSample_GetSampleTime(output_sample
, &time
);
2067 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2068 ok(md
->time
== time
, "Unexpected time.\n");
2069 hr
= IMFSample_GetSampleDuration(output_sample
, &time
);
2070 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2071 ok(md
->duration
== time
, "Unexpected duration.\n");
2073 ref
= IMFSample_Release(input_sample
);
2074 ok(ref
== 0, "Release returned %ld\n", ref
);
2075 ref
= IMFSample_Release(output_sample
);
2076 ok(ref
== 0, "Release returned %ld\n", ref
);
2079 static void test_sample_copier_output_processing(void)
2081 IMFMediaBuffer
*input_buffer
, *output_buffer
;
2082 MFT_OUTPUT_STREAM_INFO output_info
;
2083 struct sample_metadata md
;
2084 IMFMediaType
*mediatype
;
2085 IMFTransform
*copier
;
2091 if (!pMFCreateSampleCopierMFT
)
2094 hr
= pMFCreateSampleCopierMFT(&copier
);
2095 ok(hr
== S_OK
, "Failed to create sample copier, hr %#lx.\n", hr
);
2097 /* Configure for 16 x 16 of D3DFMT_X8R8G8B8. */
2098 hr
= MFCreateMediaType(&mediatype
);
2099 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
2101 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
2102 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2104 hr
= IMFMediaType_SetGUID(mediatype
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
2105 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2107 hr
= IMFMediaType_SetUINT64(mediatype
, &MF_MT_FRAME_SIZE
, ((UINT64
)16) << 32 | 16);
2108 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
2110 hr
= IMFTransform_SetInputType(copier
, 0, mediatype
, 0);
2111 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
2113 hr
= IMFTransform_SetOutputType(copier
, 0, mediatype
, 0);
2114 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
2116 /* Source and destination are linear buffers, destination is twice as large. */
2117 hr
= IMFTransform_GetOutputStreamInfo(copier
, 0, &output_info
);
2118 ok(hr
== S_OK
, "Failed to get output info, hr %#lx.\n", hr
);
2120 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &output_buffer
);
2121 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
2123 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
2124 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2125 memset(ptr
, 0xcc, max_length
);
2126 hr
= IMFMediaBuffer_Unlock(output_buffer
);
2127 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2129 hr
= MFCreateAlignedMemoryBuffer(output_info
.cbSize
, output_info
.cbAlignment
, &input_buffer
);
2130 ok(hr
== S_OK
, "Failed to create media buffer, hr %#lx.\n", hr
);
2132 hr
= IMFMediaBuffer_Lock(input_buffer
, &ptr
, &max_length
, NULL
);
2133 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2134 memset(ptr
, 0xaa, max_length
);
2135 hr
= IMFMediaBuffer_Unlock(input_buffer
);
2136 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2137 hr
= IMFMediaBuffer_SetCurrentLength(input_buffer
, 4);
2138 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2140 sample_copier_process(copier
, input_buffer
, output_buffer
, NULL
);
2142 hr
= IMFMediaBuffer_Lock(output_buffer
, &ptr
, &max_length
, NULL
);
2143 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2144 ok(ptr
[0] == 0xaa && ptr
[4] == 0xcc, "Unexpected buffer contents.\n");
2146 hr
= IMFMediaBuffer_Unlock(output_buffer
);
2147 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
2152 sample_copier_process(copier
, input_buffer
, output_buffer
, &md
);
2154 ref
= IMFMediaBuffer_Release(input_buffer
);
2155 ok(ref
== 0, "Release returned %ld\n", ref
);
2156 ref
= IMFMediaBuffer_Release(output_buffer
);
2157 ok(ref
== 0, "Release returned %ld\n", ref
);
2159 ref
= IMFTransform_Release(copier
);
2160 ok(ref
== 0, "Release returned %ld\n", ref
);
2161 ref
= IMFMediaType_Release(mediatype
);
2162 ok(ref
== 0, "Release returned %ld\n", ref
);
2165 static IMFSample
*create_sample(const BYTE
*data
, ULONG size
)
2167 IMFMediaBuffer
*media_buffer
;
2174 hr
= MFCreateSample(&sample
);
2175 ok(hr
== S_OK
, "MFCreateSample returned %#lx\n", hr
);
2176 hr
= MFCreateMemoryBuffer(size
, &media_buffer
);
2177 ok(hr
== S_OK
, "MFCreateMemoryBuffer returned %#lx\n", hr
);
2178 hr
= IMFMediaBuffer_Lock(media_buffer
, &buffer
, NULL
, &length
);
2179 ok(hr
== S_OK
, "Lock returned %#lx\n", hr
);
2180 ok(length
== 0, "got length %lu\n", length
);
2181 if (!data
) memset(buffer
, 0xcd, size
);
2182 else memcpy(buffer
, data
, size
);
2183 hr
= IMFMediaBuffer_Unlock(media_buffer
);
2184 ok(hr
== S_OK
, "Unlock returned %#lx\n", hr
);
2185 hr
= IMFMediaBuffer_SetCurrentLength(media_buffer
, data
? size
: 0);
2186 ok(hr
== S_OK
, "SetCurrentLength returned %#lx\n", hr
);
2187 hr
= IMFSample_AddBuffer(sample
, media_buffer
);
2188 ok(hr
== S_OK
, "AddBuffer returned %#lx\n", hr
);
2189 ret
= IMFMediaBuffer_Release(media_buffer
);
2190 ok(ret
== 1, "Release returned %lu\n", ret
);
2195 static const BYTE aac_codec_data
[14] = {0x00,0x00,0x29,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x08};
2197 static void test_aac_encoder(void)
2199 const GUID
*const class_id
= &CLSID_AACMFTEncoder
;
2200 const struct transform_info expect_mft_info
=
2202 .name
= L
"Microsoft AAC Audio Encoder MFT",
2203 .major_type
= &MFMediaType_Audio
,
2206 {.subtype
= &MFAudioFormat_PCM
},
2210 {.subtype
= &MFAudioFormat_AAC
},
2214 static const struct attribute_desc input_type_desc
[] =
2216 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2217 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2218 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2219 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2220 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2223 const struct attribute_desc output_type_desc
[] =
2225 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2226 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
2227 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2228 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2229 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2230 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000, .required
= TRUE
),
2234 static const struct attribute_desc expect_input_type_desc
[] =
2236 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
2237 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2238 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2239 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2240 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2241 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
2242 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2243 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 2),
2244 ATTR_UINT32(MF_MT_AVG_BITRATE
, 44100 * 2 * 8),
2245 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
2246 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
2247 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2248 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2251 const struct attribute_desc expect_output_type_desc
[] =
2253 ATTR_GUID(MF_MT_AM_FORMAT_TYPE
, FORMAT_WaveFormatEx
),
2254 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2255 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2256 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2257 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2258 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
2259 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2260 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
2261 ATTR_UINT32(MF_MT_AVG_BITRATE
, 96000),
2262 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
2263 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
2264 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2265 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
2266 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2267 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
)),
2270 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0}, output_info
= {.cbSize
= 0x600};
2271 const MFT_INPUT_STREAM_INFO input_info
= {0};
2273 const struct buffer_desc output_buffer_desc
[] =
2275 {.length
= -1 /* variable */},
2277 const struct attribute_desc output_sample_attributes
[] =
2279 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2282 const struct sample_desc output_sample_desc
[] =
2286 .attributes
= output_sample_attributes
,
2287 .sample_time
= 0, .sample_duration
= 113823,
2288 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2292 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
2293 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
2294 IMFSample
*input_sample
, *output_sample
;
2295 IMFCollection
*output_samples
;
2296 ULONG i
, ret
, audio_data_len
;
2297 DWORD length
, output_status
;
2298 IMFTransform
*transform
;
2299 const BYTE
*audio_data
;
2303 hr
= CoInitialize(NULL
);
2304 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2306 winetest_push_context("aacenc");
2308 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2310 check_mft_get_info(class_id
, &expect_mft_info
);
2312 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2313 &IID_IMFTransform
, (void **)&transform
)))
2316 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2317 check_interface(transform
, &IID_IMediaObject
, FALSE
);
2318 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
2319 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
2321 check_mft_optional_methods(transform
, 1);
2322 check_mft_get_attributes(transform
, NULL
, FALSE
);
2323 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2324 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
2326 check_mft_set_output_type_required(transform
, output_type_desc
);
2327 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2328 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2330 check_mft_set_input_type_required(transform
, input_type_desc
);
2331 check_mft_set_input_type(transform
, input_type_desc
);
2332 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2334 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2335 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2337 if (!has_video_processor
)
2339 win_skip("Skipping AAC encoder tests on Win7\n");
2343 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2344 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2346 input_sample
= create_sample(audio_data
, audio_data_len
);
2347 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2348 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2349 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2350 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2351 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2352 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2353 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2354 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2355 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2356 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2357 ref
= IMFSample_Release(input_sample
);
2358 ok(ref
<= 1, "Release returned %ld\n", ref
);
2360 hr
= MFCreateCollection(&output_samples
);
2361 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2363 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2364 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2366 winetest_push_context("%lu", i
);
2367 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2368 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2369 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2370 ref
= IMFSample_Release(output_sample
);
2371 ok(ref
== 1, "Release returned %ld\n", ref
);
2372 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2373 winetest_pop_context();
2375 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2376 ret
= IMFSample_Release(output_sample
);
2377 ok(ret
== 0, "Release returned %lu\n", ret
);
2378 ok(i
== 88, "got %lu output samples\n", i
);
2380 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacencdata.bin");
2381 ok(ret
== 0, "got %lu%% diff\n", ret
);
2382 IMFCollection_Release(output_samples
);
2384 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2385 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2386 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2387 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2388 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2389 ok(length
== 0, "got length %lu\n", length
);
2390 ret
= IMFSample_Release(output_sample
);
2391 ok(ret
== 0, "Release returned %lu\n", ret
);
2394 ret
= IMFTransform_Release(transform
);
2395 ok(ret
== 0, "Release returned %lu\n", ret
);
2398 winetest_pop_context();
2402 static void test_aac_decoder_subtype(const struct attribute_desc
*input_type_desc
)
2404 const GUID
*const class_id
= &CLSID_MSAACDecMFT
;
2405 const struct transform_info expect_mft_info
=
2407 .name
= L
"Microsoft AAC Audio Decoder MFT",
2408 .major_type
= &MFMediaType_Audio
,
2411 {.subtype
= &MFAudioFormat_AAC
},
2412 {.subtype
= &MFAudioFormat_RAW_AAC1
},
2413 {.subtype
= &MFAudioFormat_ADTS
, .broken
= TRUE
/* <= w8 */},
2417 {.subtype
= &MFAudioFormat_Float
},
2418 {.subtype
= &MFAudioFormat_PCM
},
2422 static const struct attribute_desc expect_input_attributes
[] =
2424 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2425 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2426 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2427 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 6),
2428 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 24),
2429 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
2430 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 1152000),
2433 static const media_type_desc expect_available_inputs
[] =
2436 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2437 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2438 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2439 /* MF_MT_USER_DATA with some AAC codec data */
2442 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_RAW_AAC1
),
2445 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2446 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2447 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 1),
2448 /* MF_MT_USER_DATA with some AAC codec data */
2451 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
),
2452 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 0),
2453 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 3),
2454 /* MF_MT_USER_DATA with some AAC codec data */
2457 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_ADTS
),
2460 static const struct attribute_desc expect_output_attributes
[] =
2462 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2463 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2464 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2465 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
2466 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2469 static const media_type_desc expect_available_outputs
[] =
2472 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2473 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2474 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2475 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
2476 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4 * 44100),
2479 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2480 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
2481 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2482 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
2483 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * 44100),
2486 const struct attribute_desc expect_transform_attributes
[] =
2488 ATTR_UINT32(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE
, !has_video_processor
/* 1 on W7 */, .todo
= TRUE
),
2489 /* more AAC decoder specific attributes from CODECAPI */
2492 static const struct attribute_desc output_type_desc
[] =
2494 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2495 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
2496 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1, .required
= TRUE
),
2497 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
2498 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2501 const MFT_OUTPUT_STREAM_INFO output_info
=
2503 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
,
2506 const MFT_INPUT_STREAM_INFO input_info
=
2508 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
2509 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_INPUT_STREAM_HOLDS_BUFFERS
,
2512 const struct buffer_desc output_buffer_desc
[] =
2516 const struct attribute_desc output_sample_attributes
[] =
2518 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2521 const struct sample_desc output_sample_desc
[] =
2524 .attributes
= output_sample_attributes
+ (has_video_processor
? 0 : 1) /* MFSampleExtension_CleanPoint missing on Win7 */,
2525 .sample_time
= 0, .sample_duration
= 232200,
2526 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2530 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2531 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_AAC
};
2532 IMFSample
*input_sample
, *output_sample
;
2533 ULONG i
, ret
, ref
, aacenc_data_len
;
2534 IMFCollection
*output_samples
;
2535 DWORD length
, output_status
;
2536 IMFMediaType
*media_type
;
2537 IMFTransform
*transform
;
2538 const BYTE
*aacenc_data
;
2542 hr
= CoInitialize(NULL
);
2543 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2545 winetest_push_context("aacdec");
2547 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
2549 check_mft_get_info(class_id
, &expect_mft_info
);
2551 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2552 &IID_IMFTransform
, (void **)&transform
)))
2555 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2556 check_interface(transform
, &IID_IMediaObject
, FALSE
);
2557 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
2558 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
2560 check_mft_optional_methods(transform
, 1);
2561 check_mft_get_attributes(transform
, expect_transform_attributes
, FALSE
);
2562 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2563 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2565 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
2566 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
2569 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
2571 winetest_push_context("in %lu", i
);
2572 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
2573 check_media_type(media_type
, expect_input_attributes
, -1);
2574 check_media_type(media_type
, expect_available_inputs
[i
], -1);
2575 ret
= IMFMediaType_Release(media_type
);
2576 ok(ret
<= 1, "Release returned %lu\n", ret
);
2577 winetest_pop_context();
2579 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
2580 ok(i
== ARRAY_SIZE(expect_available_inputs
)
2581 || broken(i
== 2) /* w7 */ || broken(i
== 4) /* w8 */,
2582 "%lu input media types\n", i
);
2584 /* setting output media type first doesn't work */
2585 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
2586 check_mft_get_output_current_type(transform
, NULL
);
2588 check_mft_set_input_type_required(transform
, input_type_desc
);
2589 check_mft_set_input_type(transform
, input_type_desc
);
2590 check_mft_get_input_current_type(transform
, input_type_desc
);
2592 /* check new output media types */
2595 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
2597 winetest_push_context("out %lu", i
);
2598 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
2599 check_media_type(media_type
, expect_output_attributes
, -1);
2600 check_media_type(media_type
, expect_available_outputs
[i
], -1);
2601 ret
= IMFMediaType_Release(media_type
);
2602 ok(ret
<= 1, "Release returned %lu\n", ret
);
2603 winetest_pop_context();
2605 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
2606 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
2608 check_mft_set_output_type_required(transform
, output_type_desc
);
2609 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2610 check_mft_get_output_current_type(transform
, output_type_desc
);
2612 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2613 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2615 load_resource(L
"aacencdata.bin", &aacenc_data
, &aacenc_data_len
);
2616 ok(aacenc_data_len
== 24861, "got length %lu\n", aacenc_data_len
);
2618 input_sample
= create_sample(aacenc_data
+ sizeof(DWORD
), *(DWORD
*)aacenc_data
);
2621 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2622 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2623 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
2624 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2625 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2627 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2628 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2629 ok(!flags
, "Got flags %#lx.\n", flags
);
2630 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2631 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2633 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2634 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2635 ok(!flags
, "Got flags %#lx.\n", flags
);
2637 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
2638 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
2640 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
2641 ok(hr
== E_INVALIDARG
, "ProcessOutput returned %#lx\n", hr
);
2642 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2644 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2645 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2646 ok(!flags
, "Got flags %#lx.\n", flags
);
2647 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2648 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2650 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2651 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2653 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2654 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2655 ok(!flags
, "Got flags %#lx.\n", flags
);
2656 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2657 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2659 hr
= MFCreateCollection(&output_samples
);
2660 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2662 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2663 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2665 winetest_push_context("%lu", i
);
2666 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2667 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2668 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2669 ref
= IMFSample_Release(output_sample
);
2670 ok(ref
== 1, "Release returned %ld\n", ref
);
2671 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2672 winetest_pop_context();
2674 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2677 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
2678 ok(hr
== S_OK
, "Got %#lx\n", hr
);
2679 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
2681 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2682 ret
= IMFSample_Release(output_sample
);
2683 ok(ret
== 0, "Release returned %lu\n", ret
);
2684 ok(i
== 1, "got %lu output samples\n", i
);
2686 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"aacdecdata.bin");
2687 todo_wine_if(ret
<= 5)
2688 ok(ret
== 0, "got %lu%% diff\n", ret
);
2689 IMFCollection_Release(output_samples
);
2691 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2692 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2693 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2694 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
, "got output[0].dwStatus %#lx\n", output_status
);
2695 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2696 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2697 ok(length
== 0, "got length %lu\n", length
);
2698 ret
= IMFSample_Release(output_sample
);
2699 ok(ret
== 0, "Release returned %lu\n", ret
);
2701 ret
= IMFSample_Release(input_sample
);
2702 ok(ret
== 0, "Release returned %lu\n", ret
);
2703 ret
= IMFTransform_Release(transform
);
2704 ok(ret
== 0, "Release returned %lu\n", ret
);
2707 winetest_pop_context();
2711 static void test_aac_decoder(void)
2713 static const BYTE aac_raw_codec_data
[] = {0x12, 0x08};
2714 static const struct attribute_desc raw_aac_input_type_desc
[] =
2716 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2717 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_RAW_AAC1
, .required
= TRUE
),
2718 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2719 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2720 ATTR_BLOB(MF_MT_USER_DATA
, aac_raw_codec_data
, sizeof(aac_raw_codec_data
), .required
= TRUE
),
2723 static const struct attribute_desc aac_input_type_desc
[] =
2725 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2726 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_AAC
, .required
= TRUE
),
2727 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
2728 ATTR_BLOB(MF_MT_USER_DATA
, aac_codec_data
, sizeof(aac_codec_data
), .required
= TRUE
),
2729 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
2730 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
2731 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 12000),
2732 ATTR_UINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION
, 41),
2733 ATTR_UINT32(MF_MT_AAC_PAYLOAD_TYPE
, 0),
2737 test_aac_decoder_subtype(aac_input_type_desc
);
2738 test_aac_decoder_subtype(raw_aac_input_type_desc
);
2741 static const BYTE wma_codec_data
[10] = {0, 0x44, 0, 0, 0x17, 0, 0, 0, 0, 0};
2742 static const ULONG wmaenc_block_size
= 1487;
2743 static const ULONG wmadec_block_size
= 0x2000;
2745 static void test_wma_encoder(void)
2747 const GUID
*const class_id
= &CLSID_CWMAEncMediaObject
;
2748 const struct transform_info expect_mft_info
=
2750 .name
= L
"WMAudio Encoder MFT",
2751 .major_type
= &MFMediaType_Audio
,
2754 {.subtype
= &MFAudioFormat_PCM
},
2755 {.subtype
= &MFAudioFormat_Float
},
2759 {.subtype
= &MFAudioFormat_WMAudioV8
},
2760 {.subtype
= &MFAudioFormat_WMAudioV9
},
2761 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
2764 const struct transform_info expect_dmo_info
=
2766 .name
= L
"WMAudio Encoder DMO",
2767 .major_type
= &MEDIATYPE_Audio
,
2770 {.subtype
= &MEDIASUBTYPE_PCM
},
2774 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
2775 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
2776 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
2780 static const struct attribute_desc input_type_desc
[] =
2782 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2783 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
2784 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2785 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
2786 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2787 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
2788 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
2791 const struct attribute_desc output_type_desc
[] =
2793 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
2794 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
2795 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
2796 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
2797 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003, .required
= TRUE
),
2798 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
2799 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
2802 static const struct attribute_desc expect_input_type_desc
[] =
2804 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2805 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
2806 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
2807 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2808 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
2809 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2810 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
2811 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
2812 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
2815 const struct attribute_desc expect_output_type_desc
[] =
2817 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
2818 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
2819 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
2820 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
2821 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
2822 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
2823 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
2824 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
2827 const MFT_OUTPUT_STREAM_INFO output_info
=
2829 .cbSize
= wmaenc_block_size
,
2832 const MFT_INPUT_STREAM_INFO input_info
=
2834 .hnsMaxLatency
= 19969161,
2839 const struct buffer_desc output_buffer_desc
[] =
2841 {.length
= wmaenc_block_size
},
2843 const struct attribute_desc output_sample_attributes
[] =
2845 ATTR_UINT32(mft_output_sample_incomplete
, 1),
2846 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
2849 const struct sample_desc output_sample_desc
[] =
2852 .attributes
= output_sample_attributes
,
2853 .sample_time
= 0, .sample_duration
= 3250794,
2854 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2857 .attributes
= output_sample_attributes
,
2858 .sample_time
= 3250794, .sample_duration
= 3715193,
2859 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2862 .attributes
= output_sample_attributes
,
2863 .sample_time
= 6965986, .sample_duration
= 3366893,
2864 .buffer_count
= 1, .buffers
= output_buffer_desc
,
2868 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
2869 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
2870 IMFSample
*input_sample
, *output_sample
;
2871 IMFCollection
*output_samples
;
2872 DWORD length
, output_status
;
2873 IMFMediaType
*media_type
;
2874 IMFTransform
*transform
;
2875 const BYTE
*audio_data
;
2876 ULONG audio_data_len
;
2881 hr
= CoInitialize(NULL
);
2882 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
2884 winetest_push_context("wmaenc");
2886 if (!check_mft_enum(MFT_CATEGORY_AUDIO_ENCODER
, &input_type
, &output_type
, class_id
))
2888 check_mft_get_info(class_id
, &expect_mft_info
);
2889 check_dmo_get_info(class_id
, &expect_dmo_info
);
2891 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
2892 &IID_IMFTransform
, (void **)&transform
)))
2895 check_interface(transform
, &IID_IMFTransform
, TRUE
);
2896 check_interface(transform
, &IID_IMediaObject
, TRUE
);
2897 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
2898 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
2900 check_mft_optional_methods(transform
, 1);
2901 check_mft_get_attributes(transform
, NULL
, FALSE
);
2902 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2903 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
2905 check_mft_set_input_type_required(transform
, input_type_desc
);
2907 hr
= MFCreateMediaType(&media_type
);
2908 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
2909 init_media_type(media_type
, input_type_desc
, -1);
2910 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
2911 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
2912 ret
= IMFMediaType_Release(media_type
);
2913 ok(ret
== 0, "Release returned %lu\n", ret
);
2915 check_mft_set_output_type_required(transform
, output_type_desc
);
2916 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
2917 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
2919 check_mft_set_input_type_required(transform
, input_type_desc
);
2920 check_mft_set_input_type(transform
, input_type_desc
);
2921 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
2923 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
2924 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
2926 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
2927 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
2929 input_sample
= create_sample(audio_data
, audio_data_len
);
2930 hr
= IMFSample_SetSampleTime(input_sample
, 0);
2931 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
2932 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
2933 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
2934 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2935 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
2936 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
2937 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
2938 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
2939 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
2940 ref
= IMFSample_Release(input_sample
);
2941 ok(ref
<= 1, "Release returned %ld\n", ref
);
2943 hr
= MFCreateCollection(&output_samples
);
2944 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
2946 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2947 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
2949 winetest_push_context("%lu", i
);
2950 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
2951 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
2952 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
2953 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
2954 ref
= IMFSample_Release(output_sample
);
2955 ok(ref
== 1, "Release returned %ld\n", ref
);
2956 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2957 winetest_pop_context();
2959 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2960 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2961 ret
= IMFSample_Release(output_sample
);
2962 ok(ret
== 0, "Release returned %lu\n", ret
);
2963 ok(i
== 3, "got %lu output samples\n", i
);
2965 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmaencdata.bin");
2966 ok(ret
== 0, "got %lu%% diff\n", ret
);
2967 IMFCollection_Release(output_samples
);
2969 output_sample
= create_sample(NULL
, output_info
.cbSize
);
2970 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
2971 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
2972 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
2973 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
2974 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
2975 ok(length
== 0, "got length %lu\n", length
);
2976 ret
= IMFSample_Release(output_sample
);
2977 ok(ret
== 0, "Release returned %lu\n", ret
);
2979 ret
= IMFTransform_Release(transform
);
2980 ok(ret
== 0, "Release returned %lu\n", ret
);
2983 winetest_pop_context();
2987 static void test_wma_decoder(void)
2989 const GUID
*const class_id
= &CLSID_CWMADecMediaObject
;
2990 const struct transform_info expect_mft_info
=
2992 .name
= L
"WMAudio Decoder MFT",
2993 .major_type
= &MFMediaType_Audio
,
2996 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
2997 {.subtype
= &MFAudioFormat_WMAudioV8
},
2998 {.subtype
= &MFAudioFormat_WMAudioV9
},
2999 {.subtype
= &MFAudioFormat_WMAudio_Lossless
},
3003 {.subtype
= &MFAudioFormat_PCM
},
3004 {.subtype
= &MFAudioFormat_Float
},
3007 const struct transform_info expect_dmo_info
=
3009 .name
= L
"WMAudio Decoder DMO",
3010 .major_type
= &MEDIATYPE_Audio
,
3013 {.subtype
= &MEDIASUBTYPE_MSAUDIO1
},
3014 {.subtype
= &MEDIASUBTYPE_WMAUDIO2
},
3015 {.subtype
= &MEDIASUBTYPE_WMAUDIO3
},
3016 {.subtype
= &MEDIASUBTYPE_WMAUDIO_LOSSLESS
},
3020 {.subtype
= &MEDIASUBTYPE_PCM
},
3021 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
3025 static const media_type_desc expect_available_inputs
[] =
3028 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3029 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_MSAUDIO1
),
3030 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3033 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3034 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
3035 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3038 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3039 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV9
),
3040 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3043 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3044 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudio_Lossless
),
3045 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3048 static const media_type_desc expect_available_outputs
[] =
3051 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3052 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
3053 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
3054 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3055 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3056 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
3057 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
3058 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3059 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3060 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3063 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3064 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3065 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3066 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3067 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3068 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
3069 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3070 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3071 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3072 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3076 const struct attribute_desc input_type_desc
[] =
3078 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3079 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
, .required
= TRUE
),
3080 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
), .required
= TRUE
),
3081 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
, .required
= TRUE
),
3082 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
3083 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3084 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003), /* not required by SetInputType, but needed for the transform to work */
3087 static const struct attribute_desc output_type_desc
[] =
3089 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
3090 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
3091 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
3092 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
3093 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
3094 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
3095 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
3098 const struct attribute_desc expect_input_type_desc
[] =
3100 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3101 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_WMAudioV8
),
3102 ATTR_BLOB(MF_MT_USER_DATA
, wma_codec_data
, sizeof(wma_codec_data
)),
3103 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, wmaenc_block_size
),
3104 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3105 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3106 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 4003),
3107 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3110 static const struct attribute_desc expect_output_type_desc
[] =
3112 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
3113 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
3114 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
3115 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
3116 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
3117 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
3118 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
3119 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
3120 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3123 const MFT_INPUT_STREAM_INFO input_info
=
3125 .cbSize
= wmaenc_block_size
,
3128 const MFT_OUTPUT_STREAM_INFO output_info
=
3130 .cbSize
= wmadec_block_size
,
3134 const struct buffer_desc output_buffer_desc
[] =
3136 {.length
= wmadec_block_size
, .compare
= compare_pcm16
},
3137 {.length
= wmadec_block_size
/ 2, .compare
= compare_pcm16
, .todo_length
= TRUE
},
3139 const struct attribute_desc output_sample_attributes
[] =
3141 ATTR_UINT32(mft_output_sample_incomplete
, 1),
3142 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3145 const struct attribute_desc output_sample_attributes_todo
[] =
3147 ATTR_UINT32(mft_output_sample_incomplete
, 1, .todo
= TRUE
),
3148 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3151 struct sample_desc output_sample_desc
[] =
3154 .attributes
= output_sample_attributes
+ 0,
3155 .sample_time
= 0, .sample_duration
= 928798,
3156 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 1,
3159 .attributes
= output_sample_attributes
+ 0,
3160 .sample_time
= 1857596, .sample_duration
= 928798,
3161 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
3164 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
3165 .sample_time
= 2786394, .sample_duration
= 464399, .todo_duration
= 928798,
3166 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
3170 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_WMAudioV8
};
3171 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
3172 IUnknown
*unknown
, *tmp_unknown
, outer
= {&test_unk_vtbl
};
3173 IMFSample
*input_sample
, *output_sample
;
3174 IMFCollection
*output_samples
;
3175 DWORD length
, output_status
;
3176 IMediaObject
*media_object
;
3177 IPropertyBag
*property_bag
;
3178 IMFMediaType
*media_type
;
3179 IMFTransform
*transform
;
3180 const BYTE
*wmaenc_data
;
3181 ULONG wmaenc_data_len
;
3185 hr
= CoInitialize(NULL
);
3186 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3188 winetest_push_context("wmadec");
3190 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
3192 check_mft_get_info(class_id
, &expect_mft_info
);
3193 check_dmo_get_info(class_id
, &expect_dmo_info
);
3195 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3196 &IID_IMFTransform
, (void **)&transform
)))
3199 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3200 check_interface(transform
, &IID_IMediaObject
, TRUE
);
3202 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
3203 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
3205 check_mft_optional_methods(transform
, 1);
3206 check_mft_get_attributes(transform
, NULL
, FALSE
);
3207 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3208 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3210 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3211 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3214 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3216 winetest_push_context("in %lu", i
);
3217 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3218 check_media_type(media_type
, expect_available_inputs
[i
], -1);
3219 ret
= IMFMediaType_Release(media_type
);
3220 ok(ret
== 0, "Release returned %lu\n", ret
);
3221 winetest_pop_context();
3224 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3226 ok(i
== 4, "%lu input media types\n", i
);
3228 /* setting output media type first doesn't work */
3229 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3230 check_mft_get_output_current_type_(transform
, NULL
, TRUE
, FALSE
);
3232 check_mft_set_input_type_required(transform
, input_type_desc
);
3233 check_mft_set_input_type(transform
, input_type_desc
);
3234 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3236 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3237 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
3239 /* check new output media types */
3242 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3244 winetest_push_context("out %lu", i
);
3245 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3246 check_media_type(media_type
, expect_available_outputs
[i
], -1);
3247 ret
= IMFMediaType_Release(media_type
);
3248 ok(ret
== 0, "Release returned %lu\n", ret
);
3249 winetest_pop_context();
3251 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3252 ok(i
== 2, "%lu output media types\n", i
);
3254 check_mft_set_output_type_required(transform
, output_type_desc
);
3255 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3256 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, TRUE
, FALSE
);
3258 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3259 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3261 load_resource(L
"wmaencdata.bin", &wmaenc_data
, &wmaenc_data_len
);
3262 ok(wmaenc_data_len
% wmaenc_block_size
== 0, "got length %lu\n", wmaenc_data_len
);
3264 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
/ 2);
3265 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3266 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3267 ret
= IMFSample_Release(input_sample
);
3268 ok(ret
== 0, "Release returned %lu\n", ret
);
3269 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
+ 1);
3270 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3271 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3272 ret
= IMFSample_Release(input_sample
);
3273 ok(ret
== 0, "Release returned %lu\n", ret
);
3274 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3275 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3276 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3277 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3278 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3279 ret
= IMFSample_Release(input_sample
);
3280 ok(ret
== 1, "Release returned %lu\n", ret
);
3282 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3283 * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */
3285 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3286 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3287 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
3288 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
3289 "got output[0].dwStatus %#lx\n", output_status
);
3291 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3292 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3293 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
3294 ret
= IMFSample_Release(input_sample
);
3295 ok(ret
== 0, "Release returned %lu\n", ret
);
3297 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3298 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3299 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
3300 || broken(output_status
== (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE
)) /* Win7 */,
3301 "got output[0].dwStatus %#lx\n", output_status
);
3303 hr
= MFCreateCollection(&output_samples
);
3304 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3306 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3307 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
3309 winetest_push_context("%lu", i
);
3310 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
3311 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3312 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3313 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3314 ref
= IMFSample_Release(output_sample
);
3315 ok(ref
== 1, "Release returned %ld\n", ref
);
3316 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3317 winetest_pop_context();
3319 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3320 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3321 ret
= IMFSample_Release(output_sample
);
3322 ok(ret
== 0, "Release returned %lu\n", ret
);
3323 todo_wine_if(i
== 3) /* wmadec output depends on ffmpeg version used */
3324 ok(i
== 4, "got %lu output samples\n", i
);
3326 if (!strcmp(winetest_platform
, "wine") && i
== 3)
3327 output_sample_desc
[1].attributes
= output_sample_attributes_todo
;
3329 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmadecdata.bin");
3330 todo_wine_if(ret
> 0 && ret
<= 10) /* ffmpeg sometimes offsets the decoded data */
3331 ok(ret
== 0, "got %lu%% diff\n", ret
);
3332 IMFCollection_Release(output_samples
);
3334 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3335 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3336 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3337 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3338 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3339 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3340 ok(length
== 0, "got length %lu\n", length
);
3341 ret
= IMFSample_Release(output_sample
);
3342 ok(ret
== 0, "Release returned %lu\n", ret
);
3344 input_sample
= create_sample(wmaenc_data
, wmaenc_block_size
);
3345 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3346 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3348 ret
= IMFTransform_Release(transform
);
3349 ok(ret
== 0, "Release returned %lu\n", ret
);
3350 ret
= IMFSample_Release(input_sample
);
3351 ok(ret
== 0, "Release returned %lu\n", ret
);
3353 hr
= CoCreateInstance( &CLSID_CWMADecMediaObject
, &outer
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
3354 (void **)&unknown
);
3355 ok( hr
== S_OK
, "CoCreateInstance returned %#lx\n", hr
);
3356 hr
= IUnknown_QueryInterface( unknown
, &IID_IMFTransform
, (void **)&transform
);
3357 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3358 hr
= IUnknown_QueryInterface( unknown
, &IID_IMediaObject
, (void **)&media_object
);
3359 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3360 hr
= IUnknown_QueryInterface( unknown
, &IID_IPropertyBag
, (void **)&property_bag
);
3361 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3362 hr
= IUnknown_QueryInterface( media_object
, &IID_IUnknown
, (void **)&tmp_unknown
);
3363 ok( hr
== S_OK
, "QueryInterface returned %#lx\n", hr
);
3365 ok( unknown
!= &outer
, "got outer IUnknown\n" );
3366 ok( transform
!= (void *)unknown
, "got IUnknown == IMFTransform\n" );
3367 ok( media_object
!= (void *)unknown
, "got IUnknown == IMediaObject\n" );
3368 ok( property_bag
!= (void *)unknown
, "got IUnknown == IPropertyBag\n" );
3369 ok( tmp_unknown
!= unknown
, "got inner IUnknown\n" );
3371 check_interface( unknown
, &IID_IPersistPropertyBag
, FALSE
);
3372 check_interface( unknown
, &IID_IAMFilterMiscFlags
, FALSE
);
3373 check_interface( unknown
, &IID_IMediaSeeking
, FALSE
);
3374 check_interface( unknown
, &IID_IMediaPosition
, FALSE
);
3375 check_interface( unknown
, &IID_IReferenceClock
, FALSE
);
3376 check_interface( unknown
, &IID_IBasicAudio
, FALSE
);
3378 ref
= IUnknown_Release( tmp_unknown
);
3379 ok( ref
== 1, "Release returned %lu\n", ref
);
3380 ref
= IPropertyBag_Release( property_bag
);
3381 ok( ref
== 1, "Release returned %lu\n", ref
);
3382 ref
= IMediaObject_Release( media_object
);
3383 ok( ref
== 1, "Release returned %lu\n", ref
);
3384 ref
= IMFTransform_Release( transform
);
3385 ok( ref
== 1, "Release returned %lu\n", ref
);
3386 ref
= IUnknown_Release( unknown
);
3387 ok( ref
== 0, "Release returned %lu\n", ref
);
3390 winetest_pop_context();
3394 #define next_h264_sample(a, b) next_h264_sample_(__LINE__, a, b)
3395 static IMFSample
*next_h264_sample_(int line
, const BYTE
**h264_buf
, ULONG
*h264_len
)
3397 const BYTE
*sample_data
;
3399 ok_(__FILE__
, line
)(*h264_len
> 4, "invalid h264 length\n");
3400 ok_(__FILE__
, line
)(*(UINT32
*)*h264_buf
== 0x01000000, "invalid h264 buffer\n");
3401 sample_data
= *h264_buf
;
3406 while (*h264_len
>= 4 && *(UINT32
*)*h264_buf
!= 0x01000000)
3412 return create_sample(sample_data
, *h264_buf
- sample_data
);
3415 static void test_h264_decoder(void)
3417 const GUID
*const class_id
= &CLSID_MSH264DecoderMFT
;
3418 const struct transform_info expect_mft_info
=
3420 .name
= L
"Microsoft H264 Video Decoder MFT",
3421 .major_type
= &MFMediaType_Video
,
3424 {.subtype
= &MFVideoFormat_H264
},
3425 {.subtype
= &MFVideoFormat_H264_ES
},
3429 {.subtype
= &MFVideoFormat_NV12
},
3430 {.subtype
= &MFVideoFormat_YV12
},
3431 {.subtype
= &MFVideoFormat_IYUV
},
3432 {.subtype
= &MFVideoFormat_I420
},
3433 {.subtype
= &MFVideoFormat_YUY2
},
3436 static const media_type_desc default_inputs
[] =
3439 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3440 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
3443 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3444 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264_ES
),
3447 static const struct attribute_desc expect_transform_attributes
[] =
3449 ATTR_UINT32(MF_LOW_LATENCY
, 0),
3450 ATTR_UINT32(MF_SA_D3D_AWARE
, 1, .todo
= TRUE
),
3451 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1),
3452 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0, .todo
= TRUE
),
3453 /* more H264 decoder specific attributes from CODECAPI */
3456 static const DWORD input_width
= 120, input_height
= 248;
3457 const media_type_desc default_outputs
[] =
3460 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3461 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3462 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3463 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3464 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3465 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3466 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3467 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3468 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3469 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3470 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3473 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3474 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3475 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3476 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3477 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3478 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3479 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3480 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3481 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3482 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3483 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3486 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3487 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3488 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3489 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3490 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3491 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3492 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3493 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3494 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3495 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3496 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3499 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3500 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3501 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3502 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3503 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
),
3504 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3505 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3506 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3507 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3508 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 3 / 2),
3509 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3512 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3513 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3514 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3515 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
3516 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, input_width
* 2),
3517 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3518 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3519 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3520 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3521 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, input_width
* input_height
* 2),
3522 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3525 const struct attribute_desc input_type_desc
[] =
3527 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3528 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
, .required
= TRUE
),
3529 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3532 const struct attribute_desc output_type_desc
[] =
3534 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
3535 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
3536 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
, .required
= TRUE
),
3537 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3538 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3539 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3540 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3541 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3544 const struct attribute_desc expect_input_type_desc
[] =
3546 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3547 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_H264
),
3548 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3549 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 0),
3550 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 0),
3551 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 0),
3552 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3553 ATTR_UINT32(MF_MT_COMPRESSED
, 1),
3556 const struct attribute_desc expect_output_type_desc
[] =
3558 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3559 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3560 ATTR_RATIO(MF_MT_FRAME_SIZE
, input_width
, input_height
),
3561 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3562 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 2, 1),
3563 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, 3840),
3564 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, 3840 * input_height
* 3 / 2),
3565 ATTR_UINT32(MF_MT_VIDEO_ROTATION
, 0),
3566 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3567 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3570 static const struct attribute_desc new_output_type_desc
[] =
3572 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3573 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3574 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3575 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3576 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3579 static const struct attribute_desc expect_new_output_type_desc
[] =
3581 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3582 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3583 ATTR_RATIO(MF_MT_FRAME_SIZE
, 96, 96),
3584 ATTR_RATIO(MF_MT_FRAME_RATE
, 1, 1),
3585 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 2),
3586 ATTR_UINT32(MF_MT_COMPRESSED
, 0),
3587 ATTR_UINT32(MF_MT_AVG_BIT_ERROR_RATE
, 0),
3590 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
3591 static const DWORD actual_width
= 96, actual_height
= 96;
3592 const media_type_desc actual_outputs
[] =
3595 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3596 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
3597 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3598 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3599 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3600 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3601 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3602 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3603 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3604 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3605 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3606 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3609 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3610 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
3611 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3612 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3613 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3614 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3615 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3616 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3617 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3618 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3619 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3620 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3623 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3624 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
3625 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3626 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3627 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3628 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3629 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3630 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3631 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3632 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3633 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3634 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3637 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3638 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
3639 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3640 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3641 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3642 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
3643 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
3644 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3645 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3646 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3647 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3648 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3651 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
3652 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
3653 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
3654 ATTR_RATIO(MF_MT_FRAME_RATE
, 60000, 1000),
3655 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
3656 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
3657 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
3658 /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
3659 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 7),
3660 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
3661 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
3662 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
3665 const MFT_OUTPUT_STREAM_INFO initial_output_info
=
3667 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3668 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3669 .cbSize
= 1920 * 1088 * 2,
3671 const MFT_OUTPUT_STREAM_INFO output_info
=
3673 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3674 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3675 .cbSize
= input_width
* input_height
* 2,
3677 const MFT_OUTPUT_STREAM_INFO actual_output_info
=
3679 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3680 MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
,
3681 .cbSize
= actual_width
* actual_height
* 2,
3683 const MFT_INPUT_STREAM_INFO input_info
=
3685 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
|
3686 MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE
,
3690 const struct attribute_desc output_sample_attributes
[] =
3692 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
3695 const struct buffer_desc output_buffer_desc_nv12
=
3697 .length
= actual_width
* actual_height
* 3 / 2,
3698 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
3700 const struct sample_desc output_sample_desc_nv12
=
3702 .attributes
= output_sample_attributes
,
3703 .sample_time
= 0, .sample_duration
= 333667,
3704 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
3706 const struct buffer_desc output_buffer_desc_i420
=
3708 .length
= actual_width
* actual_height
* 3 / 2,
3709 .compare
= compare_i420
, .dump
= dump_i420
, .rect
= {.right
= 82, .bottom
= 84},
3711 const struct sample_desc expect_output_sample_i420
=
3713 .attributes
= output_sample_attributes
,
3714 .sample_time
= 333667, .sample_duration
= 333667,
3715 .buffer_count
= 1, .buffers
= &output_buffer_desc_i420
,
3718 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_H264
};
3719 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
3720 IMFSample
*input_sample
, *output_sample
;
3721 const BYTE
*h264_encoded_data
;
3722 IMFCollection
*output_samples
;
3723 ULONG h264_encoded_data_len
;
3724 DWORD length
, output_status
;
3725 IMFAttributes
*attributes
;
3726 IMFMediaType
*media_type
;
3727 IMFTransform
*transform
;
3732 hr
= CoInitialize(NULL
);
3733 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
3735 winetest_push_context("h264dec");
3737 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
3739 check_mft_get_info(class_id
, &expect_mft_info
);
3741 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
3742 &IID_IMFTransform
, (void **)&transform
)))
3745 check_interface(transform
, &IID_IMFTransform
, TRUE
);
3746 check_interface(transform
, &IID_IMediaObject
, FALSE
);
3747 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
3748 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
3750 check_mft_optional_methods(transform
, 1);
3751 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
3752 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3753 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
3755 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
3756 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
3757 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
3758 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
3759 IMFAttributes_Release(attributes
);
3761 /* no output type is available before an input type is set */
3763 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
3764 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
3767 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3768 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Got %#lx\n", hr
);
3769 ok(flags
== 0xdeadbeef, "Got flags %#lx.\n", flags
);
3771 /* setting output media type first doesn't work */
3772 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
3773 check_mft_get_output_current_type(transform
, NULL
);
3775 /* check available input types */
3778 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
3780 winetest_push_context("in %lu", i
);
3781 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
3782 check_media_type(media_type
, default_inputs
[i
], -1);
3783 ret
= IMFMediaType_Release(media_type
);
3784 ok(ret
== 0, "Release returned %lu\n", ret
);
3785 winetest_pop_context();
3787 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
3788 ok(i
== 2 || broken(i
== 1) /* Win7 */, "%lu input media types\n", i
);
3790 check_mft_set_input_type_required(transform
, input_type_desc
);
3791 check_mft_set_input_type(transform
, input_type_desc
);
3792 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, TRUE
, FALSE
);
3794 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3795 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3797 /* output types can now be enumerated (though they are actually the same for all input types) */
3800 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3802 winetest_push_context("out %lu", i
);
3803 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3804 check_media_type(media_type
, default_outputs
[i
], -1);
3805 ret
= IMFMediaType_Release(media_type
);
3806 ok(ret
== 0, "Release returned %lu\n", ret
);
3807 winetest_pop_context();
3809 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3810 ok(i
== 5, "%lu output media types\n", i
);
3812 check_mft_set_output_type_required(transform
, output_type_desc
);
3813 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
3814 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3816 /* check that the output media type we've selected don't change the enumeration */
3819 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3821 winetest_push_context("out %lu", i
);
3822 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3823 check_media_type(media_type
, default_outputs
[i
], -1);
3824 ret
= IMFMediaType_Release(media_type
);
3825 ok(ret
== 0, "Release returned %lu\n", ret
);
3826 winetest_pop_context();
3828 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3829 ok(i
== 5, "%lu output media types\n", i
);
3831 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3832 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
3834 load_resource(L
"h264data.bin", &h264_encoded_data
, &h264_encoded_data_len
);
3836 /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES
3837 * IMFTransform_ProcessOutput needs a sample or returns an error */
3839 hr
= check_mft_process_output(transform
, NULL
, &output_status
);
3840 ok(hr
== E_INVALIDARG
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3841 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3844 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3847 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3848 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3849 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
) break;
3851 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3852 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3853 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3854 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3855 ok(length
== 0, "got length %lu\n", length
);
3856 ret
= IMFSample_Release(output_sample
);
3857 ok(ret
== 0, "Release returned %lu\n", ret
);
3860 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3861 ok(hr
== S_OK
, "Got %#lx\n", hr
);
3862 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
3863 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3864 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3865 ret
= IMFSample_Release(input_sample
);
3866 ok(ret
<= 1, "Release returned %lu\n", ret
);
3867 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3870 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
3871 ok(hr
== S_OK
, "Got %#lx\n", hr
);
3872 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
3873 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3874 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3875 ret
= IMFSample_Release(input_sample
);
3876 ok(ret
<= 1, "Release returned %lu\n", ret
);
3877 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3880 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3881 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3882 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
3883 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
3885 ok(i
== 2, "got %lu iterations\n", i
);
3886 ok(h264_encoded_data_len
== 2425, "got h264_encoded_data_len %lu\n", h264_encoded_data_len
);
3887 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3888 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3889 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3890 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3891 ok(length
== 0, "got length %lu\n", length
);
3892 ret
= IMFSample_Release(output_sample
);
3893 ok(ret
== 0, "Release returned %lu\n", ret
);
3895 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
3896 check_mft_get_output_stream_info(transform
, S_OK
, &actual_output_info
);
3899 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
3901 winetest_push_context("out %lu", i
);
3902 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
3903 check_media_type(media_type
, actual_outputs
[i
], -1);
3904 ret
= IMFMediaType_Release(media_type
);
3905 ok(ret
== 0, "Release returned %lu\n", ret
);
3906 winetest_pop_context();
3908 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
3909 ok(i
== 5, "%lu output media types\n", i
);
3911 /* current output type is still the one we selected */
3912 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
3914 hr
= MFCreateCollection(&output_samples
);
3915 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3917 output_sample
= create_sample(NULL
, output_info
.cbSize
);
3918 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3919 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3920 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3921 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3922 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3923 ref
= IMFSample_Release(output_sample
);
3924 ok(ref
== 1, "Release returned %ld\n", ref
);
3926 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
3927 ok(ret
== 0, "got %lu%% diff\n", ret
);
3928 IMFCollection_Release(output_samples
);
3930 /* we can change it, but only with the correct frame size */
3931 hr
= MFCreateMediaType(&media_type
);
3932 ok(hr
== S_OK
, "MFCreateMediaType returned %#lx\n", hr
);
3933 init_media_type(media_type
, output_type_desc
, -1);
3934 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3935 ok(hr
== MF_E_INVALIDMEDIATYPE
, "SetOutputType returned %#lx.\n", hr
);
3936 init_media_type(media_type
, new_output_type_desc
, -1);
3937 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
3938 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
3939 ret
= IMFMediaType_Release(media_type
);
3940 ok(ret
== 1, "Release returned %lu\n", ret
);
3942 check_mft_get_output_current_type_(transform
, expect_new_output_type_desc
, FALSE
, TRUE
);
3944 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3945 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3947 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3949 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3951 while (hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
)
3953 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3954 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
3955 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
3956 ret
= IMFSample_Release(input_sample
);
3957 ok(ret
<= 1, "Release returned %lu\n", ret
);
3958 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
3959 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3962 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "ProcessOutput returned %#lx\n", hr
);
3963 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE
, "got output[0].dwStatus %#lx\n", output_status
);
3965 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
3966 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
3967 ok(length
== 0, "got length %lu\n", length
);
3968 ret
= IMFSample_Release(output_sample
);
3969 ok(ret
== 0, "Release returned %lu\n", ret
);
3971 hr
= MFCreateCollection(&output_samples
);
3972 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
3974 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3975 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3976 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
3977 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3978 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
3979 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
3980 ref
= IMFSample_Release(output_sample
);
3981 ok(ref
== 1, "Release returned %ld\n", ref
);
3983 ret
= check_mf_sample_collection(output_samples
, &expect_output_sample_i420
, L
"i420frame.bmp");
3984 todo_wine
/* wg_transform_set_output_format() should convert already processed samples instead of dropping */
3985 ok(ret
== 0, "got %lu%% diff\n", ret
);
3986 IMFCollection_Release(output_samples
);
3988 output_sample
= create_sample(NULL
, actual_width
* actual_height
* 2);
3989 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
3990 todo_wine_if(hr
== S_OK
) /* when VA-API plugin is used */
3991 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
3992 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
3993 ret
= IMFSample_Release(output_sample
);
3994 ok(ret
== 0, "Release returned %lu\n", ret
);
3999 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
4000 ok(hr
== S_OK
, "Got %#lx\n", hr
);
4001 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
4002 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4003 ok(hr
== S_OK
|| hr
== MF_E_NOTACCEPTING
, "Got %#lx\n", hr
);
4004 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
4005 } while (hr
== S_OK
);
4007 ok(hr
== MF_E_NOTACCEPTING
, "Got %#lx\n", hr
);
4009 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
4010 ok(hr
== S_OK
, "Got %#lx\n", hr
);
4011 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Got flags %#lx.\n", flags
);
4013 ret
= IMFTransform_Release(transform
);
4014 ok(ret
== 0, "Release returned %lu\n", ret
);
4015 ret
= IMFSample_Release(input_sample
);
4016 ok(ret
== 0, "Release returned %lu\n", ret
);
4019 winetest_pop_context();
4023 static void test_h264_decoder_concat_streams(void)
4025 const struct buffer_desc output_buffer_desc
[] =
4029 {.length
= 0, .todo_length
= TRUE
},
4031 const struct attribute_desc output_sample_attributes
[] =
4033 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4036 const struct sample_desc output_sample_desc
[] =
4039 .attributes
= output_sample_attributes
+ 0,
4040 .sample_time
= 0, .sample_duration
= 400000,
4041 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 29,
4044 .attributes
= output_sample_attributes
+ 0,
4045 .sample_time
= 12000000, .sample_duration
= 400000,
4046 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 29,
4049 .attributes
= output_sample_attributes
+ 0,
4050 .sample_time
= 0, .sample_duration
= 400000,
4051 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 29,
4055 .attributes
= output_sample_attributes
+ 0,
4056 .sample_time
= 12000000, .sample_duration
= 400000,
4057 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 6,
4061 /* Wine outputs spurious buffers */
4062 .attributes
= output_sample_attributes
+ 0,
4063 .sample_time
= 0, .sample_duration
= 400000,
4064 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 2, .repeat_count
= 22,
4065 .todo_time
= TRUE
, .todo_length
= TRUE
,
4069 const WCHAR
*filenames
[] =
4077 DWORD output_status
, input_count
, output_count
;
4078 const WCHAR
**filename
= filenames
;
4079 const BYTE
*h264_encoded_data
;
4080 IMFCollection
*output_samples
;
4081 ULONG h264_encoded_data_len
;
4082 IMFAttributes
*attributes
;
4083 IMFMediaType
*media_type
;
4084 IMFTransform
*transform
;
4085 IMFSample
*input_sample
;
4089 hr
= CoInitialize(NULL
);
4090 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4092 if (FAILED(hr
= CoCreateInstance(&CLSID_MSH264DecoderMFT
, NULL
, CLSCTX_INPROC_SERVER
,
4093 &IID_IMFTransform
, (void **)&transform
)))
4095 ok(hr
== S_OK
, "hr %#lx\n", hr
);
4097 hr
= IMFTransform_GetAttributes(transform
, &attributes
);
4098 ok(hr
== S_OK
, "GetAttributes returned %#lx\n", hr
);
4099 hr
= IMFAttributes_SetUINT32(attributes
, &MF_LOW_LATENCY
, 1);
4100 ok(hr
== S_OK
, "SetUINT32 returned %#lx\n", hr
);
4101 IMFAttributes_Release(attributes
);
4103 hr
= IMFTransform_GetInputAvailableType(transform
, 0, 0, &media_type
);
4104 ok(hr
== S_OK
, "got %#lx\n", hr
);
4105 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_RATE
, (UINT64
)25000 << 32 | 1000);
4106 ok(hr
== S_OK
, "got %#lx\n", hr
);
4107 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
4108 ok(hr
== S_OK
, "got %#lx\n", hr
);
4109 IMFMediaType_Release(media_type
);
4111 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4112 ok(hr
== S_OK
, "got %#lx\n", hr
);
4113 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_RATE
, (UINT64
)50000 << 32 | 1000);
4114 ok(hr
== S_OK
, "got %#lx\n", hr
);
4115 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
4116 ok(hr
== S_OK
, "got %#lx\n", hr
);
4117 IMFMediaType_Release(media_type
);
4119 load_resource(*filename
, &h264_encoded_data
, &h264_encoded_data_len
);
4121 hr
= MFCreateCollection(&output_samples
);
4122 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4125 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
4126 while (input_sample
)
4128 MFT_OUTPUT_STREAM_INFO info
= {0};
4130 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4131 ok(hr
== S_OK
|| hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
4133 if (hr
== S_OK
&& input_count
< 2)
4135 MFT_OUTPUT_DATA_BUFFER data
= {.pSample
= create_sample(NULL
, 1)};
4136 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &data
, &output_status
);
4137 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4138 IMFSample_Release(data
.pSample
);
4144 IMFSample_Release(input_sample
);
4146 hr
= IMFCollection_GetElementCount(output_samples
, &output_count
);
4147 ok(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
4149 if (output_count
== 96)
4151 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_FLUSH
, 0);
4152 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4155 if (h264_encoded_data_len
<= 4 && *++filename
)
4157 load_resource(*filename
, &h264_encoded_data
, &h264_encoded_data_len
);
4159 if (!wcscmp(*filename
, L
"h264data-1.bin"))
4161 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4162 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4166 if (h264_encoded_data_len
> 4)
4169 input_sample
= next_h264_sample(&h264_encoded_data
, &h264_encoded_data_len
);
4173 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4174 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4175 input_sample
= NULL
;
4179 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
4180 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
4182 while (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
)
4184 MFT_OUTPUT_DATA_BUFFER data
= {.pSample
= create_sample(NULL
, info
.cbSize
)};
4186 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &data
, &output_status
);
4187 todo_wine_if(hr
== 0xd0000001)
4188 ok(hr
== S_OK
|| hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
|| hr
== MF_E_TRANSFORM_STREAM_CHANGE
,
4189 "ProcessOutput returned %#lx\n", hr
);
4193 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)data
.pSample
);
4194 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4196 if (hr
== MF_E_TRANSFORM_STREAM_CHANGE
)
4198 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
4199 ok(hr
== S_OK
, "got %#lx\n", hr
);
4200 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_RATE
, (UINT64
)50000 << 32 | 1000);
4201 ok(hr
== S_OK
, "got %#lx\n", hr
);
4202 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
4203 ok(hr
== S_OK
, "got %#lx\n", hr
);
4204 IMFMediaType_Release(media_type
);
4205 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
4206 ok(hr
== S_OK
, "GetOutputStreamInfo returned %#lx\n", hr
);
4209 IMFSample_Release(data
.pSample
);
4213 hr
= IMFCollection_GetElementCount(output_samples
, &output_count
);
4214 ok(hr
== S_OK
, "GetElementCount returned %#lx\n", hr
);
4216 ok(output_count
== 96, "GetElementCount returned %#lx\n", output_count
);
4218 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, NULL
);
4219 ok(ret
== 0, "got %lu%% diff\n", ret
);
4221 ret
= IMFTransform_Release(transform
);
4222 ok(ret
== 0, "Release returned %lu\n", ret
);
4228 static void test_audio_convert(void)
4230 const GUID
*const class_id
= &CLSID_CResamplerMediaObject
;
4231 const struct transform_info expect_mft_info
=
4233 .name
= L
"Resampler MFT",
4234 .major_type
= &MFMediaType_Audio
,
4237 {.subtype
= &MFAudioFormat_PCM
},
4238 {.subtype
= &MFAudioFormat_Float
},
4242 {.subtype
= &MFAudioFormat_PCM
},
4243 {.subtype
= &MFAudioFormat_Float
},
4246 const struct transform_info expect_dmo_info
=
4248 .name
= L
"Resampler DMO",
4249 .major_type
= &MEDIATYPE_Audio
,
4252 {.subtype
= &MEDIASUBTYPE_PCM
},
4253 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
4257 {.subtype
= &MEDIASUBTYPE_PCM
},
4258 {.subtype
= &MEDIASUBTYPE_IEEE_FLOAT
},
4262 static const media_type_desc expect_available_inputs
[] =
4265 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4266 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
4267 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4270 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4271 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4272 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4275 static const media_type_desc expect_available_outputs
[] =
4278 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4279 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
4280 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4283 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4284 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4285 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4288 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4289 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
4290 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
4291 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4292 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
4293 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 384000),
4294 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
4295 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4296 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
4299 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4300 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4301 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
4302 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4303 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 48000),
4304 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 192000),
4305 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
4306 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4307 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
4311 static const struct attribute_desc input_type_desc
[] =
4313 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
4314 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
, .required
= TRUE
),
4315 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
4316 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32, .required
= TRUE
),
4317 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
4318 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (32 / 8), .required
= TRUE
),
4319 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (32 / 8) * 22050, .required
= TRUE
),
4322 const struct attribute_desc output_type_desc
[] =
4324 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
4325 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
4326 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
4327 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
4328 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100, .required
= TRUE
),
4329 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
4330 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 44100, .required
= TRUE
),
4333 static const struct attribute_desc expect_input_type_desc
[] =
4335 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4336 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
4337 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
4338 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4339 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
4340 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
4341 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 8),
4342 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4343 ATTR_UINT32(MF_MT_AUDIO_CHANNEL_MASK
, 3),
4346 const struct attribute_desc expect_output_type_desc
[] =
4348 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
4349 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
4350 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
4351 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
4352 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 44100),
4353 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
4354 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100 * 4),
4355 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4356 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
4359 const MFT_OUTPUT_STREAM_INFO output_info
=
4364 const MFT_INPUT_STREAM_INFO input_info
=
4370 static const ULONG audioconv_block_size
= 0x4000;
4371 const struct buffer_desc output_buffer_desc
[] =
4373 {.length
= audioconv_block_size
, .compare
= compare_pcm16
},
4374 {.length
= 0x3dd8, .compare
= compare_pcm16
, .todo_length
= TRUE
},
4375 {.length
= 0xfc, .compare
= compare_pcm16
},
4377 const struct attribute_desc output_sample_attributes
[] =
4379 ATTR_UINT32(mft_output_sample_incomplete
, 1),
4380 ATTR_UINT32(MFSampleExtension_CleanPoint
, has_video_processor
/* 0 on Win7 */, .todo
= TRUE
),
4383 const struct sample_desc output_sample_desc
[] =
4386 .attributes
= output_sample_attributes
+ 0,
4387 .sample_time
= 0, .sample_duration
= 928798,
4388 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0, .repeat_count
= 9,
4391 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
4392 .sample_time
= 9287980, .sample_duration
= 897506, .todo_duration
= 897280,
4393 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .todo_length
= TRUE
,
4396 .attributes
= output_sample_attributes
+ 0,
4397 .sample_time
= 10185486, .sample_duration
= 14286,
4398 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 2,
4402 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
4403 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_Float
};
4404 IMFSample
*input_sample
, *output_sample
;
4405 IMFCollection
*output_samples
;
4406 DWORD length
, output_status
;
4407 IMFMediaType
*media_type
;
4408 IMFTransform
*transform
;
4409 const BYTE
*audio_data
;
4410 ULONG audio_data_len
;
4414 hr
= CoInitialize(NULL
);
4415 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4417 winetest_push_context("resampler");
4419 if (!check_mft_enum(MFT_CATEGORY_AUDIO_EFFECT
, &input_type
, &output_type
, class_id
))
4421 check_mft_get_info(class_id
, &expect_mft_info
);
4422 check_dmo_get_info(class_id
, &expect_dmo_info
);
4424 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4425 &IID_IMFTransform
, (void **)&transform
)))
4428 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4429 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4430 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4431 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4432 /* check_interface(transform, &IID_IWMResamplerProps, TRUE); */
4434 check_mft_optional_methods(transform
, 1);
4435 check_mft_get_attributes(transform
, NULL
, FALSE
);
4436 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4437 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4440 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4442 winetest_push_context("out %lu", i
);
4443 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4444 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4445 ret
= IMFMediaType_Release(media_type
);
4446 ok(ret
== 0, "Release returned %lu\n", ret
);
4447 winetest_pop_context();
4449 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4450 ok(i
== 4, "%lu output media types\n", i
);
4453 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4455 winetest_push_context("in %lu", i
);
4456 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4457 check_media_type(media_type
, expect_available_inputs
[i
], -1);
4458 ret
= IMFMediaType_Release(media_type
);
4459 ok(ret
== 0, "Release returned %lu\n", ret
);
4460 winetest_pop_context();
4462 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4463 ok(i
== 2, "%lu input media types\n", i
);
4465 /* setting output media type first doesn't work */
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_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4474 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
4476 /* check new output media types */
4479 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4481 winetest_push_context("out %lu", i
);
4482 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4483 check_media_type(media_type
, expect_available_outputs
[i
], -1);
4484 ret
= IMFMediaType_Release(media_type
);
4485 ok(ret
== 0, "Release returned %lu\n", ret
);
4486 winetest_pop_context();
4488 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4489 ok(i
== 4, "%lu output media types\n", i
);
4491 check_mft_set_output_type_required(transform
, output_type_desc
);
4492 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4493 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4495 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
4496 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
4498 load_resource(L
"audiodata.bin", &audio_data
, &audio_data_len
);
4499 ok(audio_data_len
== 179928, "got length %lu\n", audio_data_len
);
4501 input_sample
= create_sample(audio_data
, audio_data_len
);
4502 hr
= IMFSample_SetSampleTime(input_sample
, 0);
4503 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4504 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
4505 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4506 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4507 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4508 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
4509 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
4510 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4511 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
4512 ret
= IMFSample_Release(input_sample
);
4513 ok(ret
<= 1, "Release returned %ld\n", ret
);
4515 hr
= MFCreateCollection(&output_samples
);
4516 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4518 output_sample
= create_sample(NULL
, audioconv_block_size
);
4519 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
4521 winetest_push_context("%lu", i
);
4522 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4523 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
4524 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4525 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4526 ref
= IMFSample_Release(output_sample
);
4527 ok(ref
== 1, "Release returned %ld\n", ref
);
4528 output_sample
= create_sample(NULL
, audioconv_block_size
);
4529 winetest_pop_context();
4531 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4532 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4533 ret
= IMFSample_Release(output_sample
);
4534 ok(ret
== 0, "Release returned %lu\n", ret
);
4536 ok(i
== 12 || broken(i
== 11) /* Win7 */, "got %lu output samples\n", i
);
4538 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"audioconvdata.bin");
4539 ok(ret
== 0, "got %lu%% diff\n", ret
);
4540 IMFCollection_Release(output_samples
);
4542 output_sample
= create_sample(NULL
, audioconv_block_size
);
4543 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4544 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4545 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
4546 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
4547 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4548 ok(length
== 0, "got length %lu\n", length
);
4549 ret
= IMFSample_Release(output_sample
);
4550 ok(ret
== 0, "Release returned %lu\n", ret
);
4552 ret
= IMFTransform_Release(transform
);
4553 ok(ret
== 0, "Release returned %lu\n", ret
);
4556 winetest_pop_context();
4560 static void test_wmv_encoder(void)
4562 const GUID
*const class_id
= &CLSID_CWMVXEncMediaObject
;
4563 const struct transform_info expect_mft_info
=
4565 .name
= L
"WMVideo8 Encoder MFT",
4566 .major_type
= &MFMediaType_Video
,
4569 {.subtype
= &MFVideoFormat_IYUV
},
4570 {.subtype
= &MFVideoFormat_I420
},
4571 {.subtype
= &MFVideoFormat_YV12
},
4572 {.subtype
= &MFVideoFormat_NV11
},
4573 {.subtype
= &MFVideoFormat_NV12
},
4574 {.subtype
= &MFVideoFormat_YUY2
},
4575 {.subtype
= &MFVideoFormat_UYVY
},
4576 {.subtype
= &MFVideoFormat_YVYU
},
4577 {.subtype
= &MFVideoFormat_YVU9
},
4578 {.subtype
= &DMOVideoFormat_RGB32
},
4579 {.subtype
= &DMOVideoFormat_RGB24
},
4580 {.subtype
= &DMOVideoFormat_RGB565
},
4581 {.subtype
= &DMOVideoFormat_RGB555
},
4582 {.subtype
= &DMOVideoFormat_RGB8
},
4586 {.subtype
= &MFVideoFormat_WMV1
},
4587 {.subtype
= &MFVideoFormat_WMV2
},
4590 const struct transform_info expect_dmo_info
=
4592 .name
= L
"WMVideo8 Encoder DMO",
4593 .major_type
= &MEDIATYPE_Video
,
4596 {.subtype
= &MEDIASUBTYPE_IYUV
},
4597 {.subtype
= &MEDIASUBTYPE_I420
},
4598 {.subtype
= &MEDIASUBTYPE_YV12
},
4599 {.subtype
= &MEDIASUBTYPE_NV11
},
4600 {.subtype
= &MEDIASUBTYPE_NV12
},
4601 {.subtype
= &MEDIASUBTYPE_YUY2
},
4602 {.subtype
= &MEDIASUBTYPE_UYVY
},
4603 {.subtype
= &MEDIASUBTYPE_YVYU
},
4604 {.subtype
= &MEDIASUBTYPE_YVU9
},
4605 {.subtype
= &MEDIASUBTYPE_RGB32
},
4606 {.subtype
= &MEDIASUBTYPE_RGB24
},
4607 {.subtype
= &MEDIASUBTYPE_RGB565
},
4608 {.subtype
= &MEDIASUBTYPE_RGB555
},
4609 {.subtype
= &MEDIASUBTYPE_RGB8
},
4613 {.subtype
= &MEDIASUBTYPE_WMV1
},
4614 {.subtype
= &MEDIASUBTYPE_WMV2
},
4618 static const media_type_desc expect_available_inputs
[] =
4621 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4622 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
4623 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4624 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4625 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4626 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4627 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4628 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4631 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4632 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
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_TRANSFER_FUNCTION
, 0),
4637 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4638 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4641 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4642 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
4643 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4644 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4645 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4646 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4647 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4648 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4651 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4652 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
4653 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4654 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4655 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4656 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4657 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4658 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4661 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4662 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4663 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4664 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4665 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4666 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4667 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4668 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4671 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4672 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
4673 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4674 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4675 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4676 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4677 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4678 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4681 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4682 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
4683 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4684 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4685 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4686 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4687 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4688 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4691 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4692 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
4693 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4694 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4695 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4696 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4697 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4698 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4701 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4702 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
4703 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4704 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4705 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4706 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4707 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4708 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4711 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4712 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
4713 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4714 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4715 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4716 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4717 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4718 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4721 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4722 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
4723 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4724 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4725 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4726 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4727 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4728 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4731 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4732 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
4733 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4734 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4735 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4736 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4737 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4738 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4741 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4742 ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
),
4743 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4744 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4745 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4746 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4747 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4748 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4751 static const media_type_desc expect_available_outputs
[] =
4754 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4755 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4756 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4757 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4758 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4759 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4762 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4763 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
),
4764 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4765 ATTR_UINT32(MF_MT_TRANSFER_FUNCTION
, 0),
4766 ATTR_UINT32(MF_MT_VIDEO_PRIMARIES
, 0),
4767 ATTR_UINT32(MF_MT_YUV_MATRIX
, 0),
4771 static const DWORD actual_width
= 96, actual_height
= 96;
4772 const struct attribute_desc input_type_desc
[] =
4774 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4775 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
4776 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4777 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
), /* required for SetOutputType */
4780 const struct attribute_desc output_type_desc
[] =
4782 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
4783 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
4784 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
4785 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001, .required
= TRUE
),
4786 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540, .required
= TRUE
),
4790 const struct attribute_desc expect_input_type_desc
[] =
4792 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4793 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
4794 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4795 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4796 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
4797 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
4798 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
4799 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4800 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
4803 const struct attribute_desc expect_output_type_desc
[] =
4805 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
4806 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
4807 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
4808 ATTR_RATIO(MF_MT_FRAME_RATE
, 30000, 1001),
4809 ATTR_UINT32(MF_MT_AVG_BITRATE
, 193540),
4810 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
4813 static const MFT_OUTPUT_STREAM_INFO empty_output_info
=
4815 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4817 static const MFT_INPUT_STREAM_INFO empty_input_info
=
4819 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4821 static const MFT_OUTPUT_STREAM_INFO expect_output_info
=
4823 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4827 static const MFT_INPUT_STREAM_INFO expect_input_info
=
4829 .dwFlags
= MFT_INPUT_STREAM_WHOLE_SAMPLES
| MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
,
4834 const struct buffer_desc output_buffer_desc
[] =
4836 {.length
= -1 /* variable */},
4838 const struct attribute_desc output_sample_attributes_key
[] =
4840 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
4843 const struct attribute_desc output_sample_attributes
[] =
4845 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0),
4848 const struct sample_desc output_sample_desc
[] =
4851 .attributes
= output_sample_attributes_key
,
4852 .sample_time
= 0, .sample_duration
= 333333,
4853 .buffer_count
= 1, .buffers
= output_buffer_desc
,
4856 .attributes
= output_sample_attributes
,
4857 .sample_time
= 333333, .sample_duration
= 333333,
4858 .buffer_count
= 1, .buffers
= output_buffer_desc
, .repeat_count
= 4
4862 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
4863 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
4864 IMFSample
*input_sample
, *output_sample
;
4865 DWORD status
, length
, output_status
;
4866 MFT_OUTPUT_DATA_BUFFER output
;
4867 IMFCollection
*output_samples
;
4868 const BYTE
*nv12frame_data
;
4869 IMFMediaType
*media_type
;
4870 ULONG nv12frame_data_len
;
4871 IMFTransform
*transform
;
4876 hr
= CoInitialize(NULL
);
4877 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
4879 winetest_push_context("wmvenc");
4881 if (!check_mft_enum(MFT_CATEGORY_VIDEO_ENCODER
, &input_type
, &output_type
, class_id
))
4883 check_mft_get_info(class_id
, &expect_mft_info
);
4884 check_dmo_get_info(class_id
, &expect_dmo_info
);
4886 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
4887 &IID_IMFTransform
, (void **)&transform
)))
4890 check_interface(transform
, &IID_IMFTransform
, TRUE
);
4891 check_interface(transform
, &IID_IMediaObject
, TRUE
);
4892 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
4893 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
4895 check_mft_optional_methods(transform
, 2);
4896 check_mft_get_attributes(transform
, NULL
, FALSE
);
4897 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_input_info
);
4898 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
4901 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
4903 winetest_push_context("in 0 %lu", i
);
4904 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
4905 ret
= IMFMediaType_Release(media_type
);
4906 ok(ret
<= 1, "Release returned %lu\n", ret
);
4907 winetest_pop_context();
4909 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
4910 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
4913 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
4915 winetest_push_context("out %lu", i
);
4916 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
4917 ret
= IMFMediaType_Release(media_type
);
4918 ok(ret
<= 1, "Release returned %lu\n", ret
);
4919 winetest_pop_context();
4921 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
4922 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
4924 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
4925 check_mft_get_output_current_type(transform
, NULL
);
4927 check_mft_set_input_type_required(transform
, input_type_desc
);
4928 check_mft_set_input_type(transform
, input_type_desc
);
4929 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
4931 check_mft_set_output_type_required(transform
, output_type_desc
);
4932 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
4933 check_mft_get_output_current_type_(transform
, expect_output_type_desc
, FALSE
, TRUE
);
4935 check_mft_get_input_stream_info(transform
, S_OK
, &expect_input_info
);
4936 check_mft_get_output_stream_info(transform
, S_OK
, &expect_output_info
);
4938 if (!has_video_processor
)
4940 win_skip("Skipping WMV encoder tests on Win7\n");
4944 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
4945 /* skip BMP header and RGB data from the dump */
4946 length
= *(DWORD
*)(nv12frame_data
+ 2);
4947 nv12frame_data_len
= nv12frame_data_len
- length
;
4948 nv12frame_data
= nv12frame_data
+ length
;
4949 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
4951 hr
= MFCreateCollection(&output_samples
);
4952 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
4954 for (i
= 0; i
< 5; i
++)
4956 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
4957 hr
= IMFSample_SetSampleTime(input_sample
, i
* 333333);
4958 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
4959 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
4960 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
4961 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
4962 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
4963 ref
= IMFSample_Release(input_sample
);
4964 ok(ref
<= 1, "Release returned %ld\n", ref
);
4966 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4967 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
4968 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
4969 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
4970 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
4971 ref
= IMFSample_Release(output_sample
);
4972 ok(ref
== 1, "Release returned %ld\n", ref
);
4975 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"wmvencdata.bin");
4976 ok(ret
== 0, "got %lu%% diff\n", ret
);
4977 IMFCollection_Release(output_samples
);
4979 output_sample
= create_sample(NULL
, expect_output_info
.cbSize
);
4980 status
= 0xdeadbeef;
4981 memset(&output
, 0, sizeof(output
));
4982 output
.pSample
= output_sample
;
4983 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, &output
, &status
);
4984 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
4985 ok(output
.pSample
== output_sample
, "got pSample %p\n", output
.pSample
);
4986 ok(output
.dwStatus
== 0, "got dwStatus %#lx\n", output
.dwStatus
);
4987 ok(status
== 0, "got status %#lx\n", status
);
4988 hr
= IMFSample_GetTotalLength(output
.pSample
, &length
);
4989 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
4990 ok(length
== 0, "got length %lu\n", length
);
4991 ret
= IMFSample_Release(output_sample
);
4992 ok(ret
== 0, "Release returned %lu\n", ret
);
4995 ret
= IMFTransform_Release(transform
);
4996 ok(ret
== 0, "Release returned %lu\n", ret
);
4999 winetest_pop_context();
5003 static void test_wmv_decoder(void)
5005 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
5006 const struct transform_info expect_mft_info
=
5008 .name
= L
"WMVideo Decoder MFT",
5009 .major_type
= &MFMediaType_Video
,
5012 {.subtype
= &MFVideoFormat_WMV1
},
5013 {.subtype
= &MFVideoFormat_WMV2
},
5014 {.subtype
= &MFVideoFormat_WMV3
},
5015 {.subtype
= &MEDIASUBTYPE_WMVP
},
5016 {.subtype
= &MEDIASUBTYPE_WVP2
},
5017 {.subtype
= &MEDIASUBTYPE_WMVR
},
5018 {.subtype
= &MEDIASUBTYPE_WMVA
},
5019 {.subtype
= &MFVideoFormat_WVC1
},
5020 {.subtype
= &MFVideoFormat_VC1S
},
5024 {.subtype
= &MFVideoFormat_YV12
},
5025 {.subtype
= &MFVideoFormat_YUY2
},
5026 {.subtype
= &MFVideoFormat_UYVY
},
5027 {.subtype
= &MFVideoFormat_YVYU
},
5028 {.subtype
= &MFVideoFormat_NV11
},
5029 {.subtype
= &MFVideoFormat_NV12
},
5030 {.subtype
= &DMOVideoFormat_RGB32
},
5031 {.subtype
= &DMOVideoFormat_RGB24
},
5032 {.subtype
= &DMOVideoFormat_RGB565
},
5033 {.subtype
= &DMOVideoFormat_RGB555
},
5034 {.subtype
= &DMOVideoFormat_RGB8
},
5037 const struct transform_info expect_dmo_info
=
5039 .name
= L
"WMVideo Decoder DMO",
5040 .major_type
= &MEDIATYPE_Video
,
5043 {.subtype
= &MEDIASUBTYPE_WMV1
},
5044 {.subtype
= &MEDIASUBTYPE_WMV2
},
5045 {.subtype
= &MEDIASUBTYPE_WMV3
},
5046 {.subtype
= &MEDIASUBTYPE_WMVA
},
5047 {.subtype
= &MEDIASUBTYPE_WVC1
},
5048 {.subtype
= &MEDIASUBTYPE_WMVP
},
5049 {.subtype
= &MEDIASUBTYPE_WVP2
},
5050 {.subtype
= &MFVideoFormat_VC1S
},
5054 {.subtype
= &MEDIASUBTYPE_YV12
},
5055 {.subtype
= &MEDIASUBTYPE_YUY2
},
5056 {.subtype
= &MEDIASUBTYPE_UYVY
},
5057 {.subtype
= &MEDIASUBTYPE_YVYU
},
5058 {.subtype
= &MEDIASUBTYPE_NV11
},
5059 {.subtype
= &MEDIASUBTYPE_NV12
},
5060 {.subtype
= &MEDIASUBTYPE_RGB32
},
5061 {.subtype
= &MEDIASUBTYPE_RGB24
},
5062 {.subtype
= &MEDIASUBTYPE_RGB565
},
5063 {.subtype
= &MEDIASUBTYPE_RGB555
},
5064 {.subtype
= &MEDIASUBTYPE_RGB8
},
5068 static const struct attribute_desc expect_common_attributes
[] =
5070 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5073 static const media_type_desc expect_available_inputs
[] =
5075 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
)},
5076 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV2
)},
5077 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVA
)},
5078 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WMVP
)},
5079 {ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_WVP2
)},
5080 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV_Unknown
)},
5081 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WVC1
)},
5082 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV3
)},
5083 {ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_VC1S
)},
5085 static const MFVideoArea actual_aperture
= {.Area
={96,96}};
5086 static const DWORD actual_width
= 96, actual_height
= 96;
5087 const struct attribute_desc expect_output_attributes
[] =
5089 ATTR_BLOB(MF_MT_GEOMETRIC_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
5090 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, sizeof(actual_aperture
)),
5091 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5092 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5093 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5094 ATTR_UINT32(MF_MT_INTERLACE_MODE
, 2),
5097 const media_type_desc expect_available_outputs
[] =
5100 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5101 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
5102 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5103 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5104 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5107 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5108 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
),
5109 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5110 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5111 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5114 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5115 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
),
5116 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5117 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5118 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5121 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5122 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
),
5123 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5124 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5125 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5128 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5129 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
),
5130 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5131 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
5132 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
5135 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5136 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
),
5137 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5138 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
5139 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
5142 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5143 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
),
5144 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5145 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
5146 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
5149 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5150 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
),
5151 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5152 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5153 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5156 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5157 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
5158 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5159 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
5160 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
5163 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5164 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
),
5165 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5166 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 3),
5167 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3),
5170 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5171 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
),
5172 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5173 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
5174 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
5175 /* ATTR_BLOB(MF_MT_PALETTE, ... with 12 elements), */
5178 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5179 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
),
5180 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5181 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
5182 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 2),
5185 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5186 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB8
),
5187 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5188 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5189 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
),
5190 /* ATTR_BLOB(MF_MT_PALETTE, ... with 904 elements), */
5193 const struct attribute_desc expect_attributes
[] =
5195 ATTR_UINT32(MF_LOW_LATENCY
, 0),
5196 ATTR_UINT32(MF_SA_D3D11_AWARE
, 1),
5197 ATTR_UINT32(MF_SA_D3D_AWARE
, 1),
5198 ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER
, 0),
5199 /* more attributes from CODECAPI */
5202 const struct attribute_desc input_type_desc
[] =
5204 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5205 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
, .required
= TRUE
),
5206 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5209 const struct attribute_desc output_type_desc
[] =
5211 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5212 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5213 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5216 const struct attribute_desc output_type_desc_negative_stride
[] =
5218 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5219 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
5220 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5221 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
),
5224 const struct attribute_desc output_type_desc_rgb
[] =
5226 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5227 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5228 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5231 const struct attribute_desc output_type_desc_rgb_negative_stride
[] =
5233 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5234 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5235 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5236 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 4),
5239 const struct attribute_desc output_type_desc_rgb_positive_stride
[] =
5241 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
5242 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
5243 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
5244 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
5247 const struct attribute_desc expect_input_type_desc
[] =
5249 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5250 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_WMV1
),
5251 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5252 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5255 const struct attribute_desc expect_output_type_desc
[] =
5257 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5258 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
5259 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5260 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
5261 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
5262 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5263 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
5264 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5265 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5268 const struct attribute_desc expect_output_type_desc_rgb
[] =
5270 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5271 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
5272 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5273 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
5274 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
5275 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5276 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
5277 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5278 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5281 const struct attribute_desc expect_output_type_desc_rgb_negative_stride
[] =
5283 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
5284 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
5285 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
5286 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 4),
5287 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
5288 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
5289 ATTR_UINT32(MF_MT_VIDEO_NOMINAL_RANGE
, 2),
5290 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
5291 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
5294 const MFT_OUTPUT_STREAM_INFO expect_output_info
=
5296 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
5300 const MFT_OUTPUT_STREAM_INFO expect_output_info_rgb
=
5302 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
5306 const MFT_OUTPUT_STREAM_INFO empty_output_info
=
5308 .dwFlags
= MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
| MFT_OUTPUT_STREAM_DISCARDABLE
,
5310 const MFT_INPUT_STREAM_INFO expect_input_info
=
5315 const MFT_INPUT_STREAM_INFO expect_input_info_rgb
=
5321 const struct attribute_desc output_sample_attributes
[] =
5323 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
5326 const struct buffer_desc output_buffer_desc_nv12
=
5328 .length
= actual_width
* actual_height
* 3 / 2,
5329 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
5331 const struct buffer_desc output_buffer_desc_rgb
=
5333 .length
= actual_width
* actual_height
* 4,
5334 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.right
= 82, .bottom
= 84},
5336 const struct sample_desc output_sample_desc_nv12
=
5338 .attributes
= output_sample_attributes
,
5339 .sample_time
= 0, .sample_duration
= 333333,
5340 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
5342 const struct sample_desc output_sample_desc_rgb
=
5344 .attributes
= output_sample_attributes
,
5345 .sample_time
= 0, .sample_duration
= 333333,
5346 .buffer_count
= 1, .buffers
= &output_buffer_desc_rgb
,
5349 const struct transform_desc
5351 const struct attribute_desc
*output_type_desc
;
5352 const struct attribute_desc
*expect_output_type_desc
;
5353 const MFT_INPUT_STREAM_INFO
*expect_input_info
;
5354 const MFT_OUTPUT_STREAM_INFO
*expect_output_info
;
5355 const struct sample_desc
*output_sample_desc
;
5356 const WCHAR
*result_bitmap
;
5363 .output_type_desc
= output_type_desc
,
5364 .expect_output_type_desc
= expect_output_type_desc
,
5365 .expect_input_info
= &expect_input_info
,
5366 .expect_output_info
= &expect_output_info
,
5367 .output_sample_desc
= &output_sample_desc_nv12
,
5368 .result_bitmap
= L
"nv12frame.bmp",
5373 /* WMV1 -> YUV (negative stride) */
5374 .output_type_desc
= output_type_desc_negative_stride
,
5375 .expect_output_type_desc
= expect_output_type_desc
,
5376 .expect_input_info
= &expect_input_info
,
5377 .expect_output_info
= &expect_output_info
,
5378 .output_sample_desc
= &output_sample_desc_nv12
,
5379 .result_bitmap
= L
"nv12frame.bmp",
5385 .output_type_desc
= output_type_desc_rgb
,
5386 .expect_output_type_desc
= expect_output_type_desc_rgb
,
5387 .expect_input_info
= &expect_input_info_rgb
,
5388 .expect_output_info
= &expect_output_info_rgb
,
5389 .output_sample_desc
= &output_sample_desc_rgb
,
5390 .result_bitmap
= L
"rgb32frame-flip.bmp",
5395 /* WMV1 -> RGB (negative stride) */
5396 .output_type_desc
= output_type_desc_rgb_negative_stride
,
5397 .expect_output_type_desc
= expect_output_type_desc_rgb_negative_stride
,
5398 .expect_input_info
= &expect_input_info_rgb
,
5399 .expect_output_info
= &expect_output_info_rgb
,
5400 .output_sample_desc
= &output_sample_desc_rgb
,
5401 .result_bitmap
= L
"rgb32frame-flip.bmp",
5406 /* WMV1 -> RGB (positive stride */
5407 .output_type_desc
= output_type_desc_rgb_positive_stride
,
5408 .expect_output_type_desc
= expect_output_type_desc_rgb
,
5409 .expect_input_info
= &expect_input_info_rgb
,
5410 .expect_output_info
= &expect_output_info_rgb
,
5411 .output_sample_desc
= &output_sample_desc_rgb
,
5412 .result_bitmap
= L
"rgb32frame-flip.bmp",
5418 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
5419 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_WMV1
};
5420 IMFSample
*input_sample
, *output_sample
;
5421 IMFCollection
*output_samples
;
5422 IMFMediaType
*media_type
;
5423 IMFTransform
*transform
;
5424 const BYTE
*wmvenc_data
;
5425 ULONG wmvenc_data_len
;
5426 DWORD output_status
;
5427 ULONG i
, j
, ret
, ref
;
5430 hr
= CoInitialize(NULL
);
5431 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
5433 winetest_push_context("wmvdec");
5435 if (!has_video_processor
)
5437 win_skip("Skipping inconsistent WMV decoder tests on Win7\n");
5441 if (!check_mft_enum(MFT_CATEGORY_VIDEO_DECODER
, &input_type
, &output_type
, class_id
))
5443 check_mft_get_info(class_id
, &expect_mft_info
);
5444 check_dmo_get_info(class_id
, &expect_dmo_info
);
5446 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
5447 &IID_IMFTransform
, (void **)&transform
)))
5450 check_interface(transform
, &IID_IMFTransform
, TRUE
);
5451 check_interface(transform
, &IID_IMediaObject
, TRUE
);
5452 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
5453 check_interface(transform
, &IID_IPropertyBag
, TRUE
);
5455 check_mft_optional_methods(transform
, 1);
5456 check_mft_get_attributes(transform
, expect_attributes
, TRUE
);
5458 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
5460 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, &empty_output_info
);
5462 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
5464 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
5467 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
5469 winetest_push_context("in %lu", i
);
5470 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
5471 check_media_type(media_type
, expect_common_attributes
, -1);
5472 check_media_type(media_type
, expect_available_inputs
[i
], -1);
5473 ret
= IMFMediaType_Release(media_type
);
5474 ok(!ret
, "Release returned %lu\n", ret
);
5475 winetest_pop_context();
5478 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
5480 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
5482 if (hr
== E_NOTIMPL
)
5485 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
5486 check_mft_get_output_current_type(transform
, NULL
);
5488 check_mft_set_input_type_required(transform
, input_type_desc
);
5489 check_mft_set_input_type(transform
, input_type_desc
);
5490 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
5493 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
5495 winetest_push_context("out %lu", i
);
5496 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
5497 check_media_type(media_type
, expect_common_attributes
, -1);
5498 check_media_type(media_type
, expect_output_attributes
, -1);
5499 check_media_type(media_type
, expect_available_outputs
[i
], -1);
5500 ret
= IMFMediaType_Release(media_type
);
5501 ok(!ret
, "Release returned %lu\n", ret
);
5502 winetest_pop_context();
5504 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
5505 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu input media types\n", i
);
5507 for (j
= 0; j
< ARRAY_SIZE(transform_tests
); j
++)
5509 winetest_push_context("transform #%lu", j
);
5511 check_mft_set_output_type_required(transform
, transform_tests
[j
].output_type_desc
);
5512 check_mft_set_output_type(transform
, transform_tests
[j
].output_type_desc
, S_OK
);
5513 check_mft_get_output_current_type_(transform
, transform_tests
[j
].expect_output_type_desc
, FALSE
, TRUE
);
5515 check_mft_get_input_stream_info(transform
, S_OK
, transform_tests
[j
].expect_input_info
);
5516 check_mft_get_output_stream_info(transform
, S_OK
, transform_tests
[j
].expect_output_info
);
5518 load_resource(L
"wmvencdata.bin", &wmvenc_data
, &wmvenc_data_len
);
5520 input_sample
= create_sample(wmvenc_data
+ sizeof(DWORD
), *(DWORD
*)wmvenc_data
);
5521 wmvenc_data_len
-= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
5522 wmvenc_data
+= *(DWORD
*)wmvenc_data
+ sizeof(DWORD
);
5523 hr
= IMFSample_SetSampleTime(input_sample
, 0);
5524 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
5525 hr
= IMFSample_SetSampleDuration(input_sample
, 333333);
5526 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
5527 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
5528 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
5529 ret
= IMFSample_Release(input_sample
);
5530 ok(ret
<= 1, "Release returned %ld\n", ret
);
5532 hr
= MFCreateCollection(&output_samples
);
5533 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
5535 output_sample
= create_sample(NULL
, transform_tests
[j
].expect_output_info
->cbSize
);
5536 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
5538 winetest_push_context("%lu", i
);
5539 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
5540 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
5541 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
5542 ref
= IMFSample_Release(output_sample
);
5543 ok(ref
== 1, "Release returned %ld\n", ref
);
5544 output_sample
= create_sample(NULL
, transform_tests
[j
].expect_output_info
->cbSize
);
5545 winetest_pop_context();
5547 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
5548 ret
= IMFSample_Release(output_sample
);
5549 ok(ret
== 0, "Release returned %lu\n", ret
);
5550 ok(i
== 1, "got %lu output samples\n", i
);
5552 ret
= check_mf_sample_collection(output_samples
, transform_tests
[j
].output_sample_desc
,
5553 transform_tests
[j
].result_bitmap
);
5554 ok(ret
<= transform_tests
[j
].delta
, "got %lu%% diff\n", ret
);
5555 IMFCollection_Release(output_samples
);
5556 winetest_pop_context();
5560 ret
= IMFTransform_Release(transform
);
5561 ok(ret
== 0, "Release returned %lu\n", ret
);
5564 winetest_pop_context();
5568 static void test_wmv_decoder_media_object(void)
5570 const GUID
*const class_id
= &CLSID_CWMVDecMediaObject
;
5571 const DMO_MEDIA_TYPE expected_input_types
[] =
5573 {MFMediaType_Video
, MEDIASUBTYPE_WMV1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5574 {MFMediaType_Video
, MEDIASUBTYPE_WMV2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5575 {MFMediaType_Video
, MEDIASUBTYPE_WMVA
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5576 {MFMediaType_Video
, MEDIASUBTYPE_WMVP
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5577 {MFMediaType_Video
, MEDIASUBTYPE_WVP2
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5578 {MFMediaType_Video
, MFVideoFormat_WMV_Unknown
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5579 {MFMediaType_Video
, MEDIASUBTYPE_WVC1
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5580 {MFMediaType_Video
, MEDIASUBTYPE_WMV3
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5581 {MFMediaType_Video
, MFVideoFormat_VC1S
, FALSE
, TRUE
, 0, GUID_NULL
, NULL
, 0},
5583 const VIDEOINFOHEADER expected_output_info
[] =
5585 {{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}},
5586 {{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}},
5587 {{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}},
5588 {{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}},
5589 {{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}},
5590 {{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}},
5591 {{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}},
5592 {{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}},
5593 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 32, BI_RGB
, 1024, 0, 0, 0, 0}},
5594 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 24, BI_RGB
, 768, 0, 0, 0, 0}},
5595 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_BITFIELDS
, 512, 0, 0, 0, 0}},
5596 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 16, BI_RGB
, 512, 0, 0, 0, 0}},
5597 {{0, 0, 16, 16}, {0, 0, 16, 16}, 0, 0, 0, {40, 16, 16, 1, 8, BI_RGB
, 256, 0, 0, 226, 226}},
5599 const DMO_MEDIA_TYPE expected_output_types
[] =
5601 {MFMediaType_Video
, MEDIASUBTYPE_NV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[0]},
5602 {MFMediaType_Video
, MEDIASUBTYPE_YV12
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[1]},
5603 {MFMediaType_Video
, MEDIASUBTYPE_IYUV
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[2]},
5604 {MFMediaType_Video
, MEDIASUBTYPE_I420
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[3]},
5605 {MFMediaType_Video
, MEDIASUBTYPE_YUY2
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[4]},
5606 {MFMediaType_Video
, MEDIASUBTYPE_UYVY
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[5]},
5607 {MFMediaType_Video
, MEDIASUBTYPE_YVYU
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[6]},
5608 {MFMediaType_Video
, MEDIASUBTYPE_NV11
, TRUE
, FALSE
, 384, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[7]},
5609 {MFMediaType_Video
, MEDIASUBTYPE_RGB32
, TRUE
, FALSE
, 1024, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[8]},
5610 {MFMediaType_Video
, MEDIASUBTYPE_RGB24
, TRUE
, FALSE
, 768, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[9]},
5611 {MFMediaType_Video
, MEDIASUBTYPE_RGB565
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 100, (BYTE
*)&expected_output_info
[10]},
5612 {MFMediaType_Video
, MEDIASUBTYPE_RGB555
, TRUE
, FALSE
, 512, FORMAT_VideoInfo
, NULL
, 88, (BYTE
*)&expected_output_info
[11]},
5613 {MFMediaType_Video
, MEDIASUBTYPE_RGB8
, TRUE
, FALSE
, 256, FORMAT_VideoInfo
, NULL
, 1112, (BYTE
*)&expected_output_info
[12]},
5615 const DWORD data_width
= 96, data_height
= 96;
5616 const POINT test_size
[] = {{16, 16}, {96, 96}, {320, 240}};
5617 const struct buffer_desc output_buffer_desc_nv12
=
5619 .length
= data_width
* data_height
* 3 / 2,
5620 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.right
= 82, .bottom
= 84},
5622 DWORD in_count
, out_count
, size
, expected_size
, alignment
, wmv_data_length
, status
, expected_status
, diff
;
5623 struct media_buffer
*input_media_buffer
= NULL
, *output_media_buffer
= NULL
;
5624 DMO_OUTPUT_DATA_BUFFER output_data_buffer
;
5625 DMO_MEDIA_TYPE media_type
, *type
;
5626 IMediaObject
*media_object
;
5627 const BYTE
*wmv_data
;
5632 winetest_push_context("wmvdec");
5634 if (!has_video_processor
)
5636 win_skip("Skipping inconsistent WMV decoder media object tests on Win7.\n");
5637 winetest_pop_context();
5641 type
= (DMO_MEDIA_TYPE
*)buffer
;
5643 hr
= CoInitialize(NULL
);
5644 ok(hr
== S_OK
, "CoInitialize failed, hr %#lx.\n", hr
);
5646 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMediaObject
, (void **)&media_object
)))
5649 winetest_pop_context();
5653 /* Test GetStreamCount. */
5654 in_count
= out_count
= 0xdeadbeef;
5655 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, &out_count
);
5656 ok(hr
== S_OK
, "GetStreamCount returned %#lx.\n", hr
);
5657 ok(in_count
== 1, "Got unexpected in_count %lu.\n", in_count
);
5658 ok(out_count
== 1, "Got unexpected in_count %lu.\n", out_count
);
5660 /* Test GetStreamCount with invalid arguments. */
5661 in_count
= out_count
= 0xdeadbeef;
5662 hr
= IMediaObject_GetStreamCount(media_object
, NULL
, &out_count
);
5663 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
5664 ok(out_count
== 0xdeadbeef, "Got unexpected out_count %lu.\n", out_count
);
5665 hr
= IMediaObject_GetStreamCount(media_object
, &in_count
, NULL
);
5666 ok(hr
== E_POINTER
, "GetStreamCount returned %#lx.\n", hr
);
5667 ok(in_count
== 0xdeadbeef, "Got unexpected in_count %lu.\n", in_count
);
5669 /* Test GetInputType. */
5670 check_dmo_get_input_type(media_object
, expected_input_types
, ARRAY_SIZE(expected_input_types
));
5672 /* Test SetInputType. */
5673 for (i
= 0; i
< ARRAY_SIZE(expected_input_types
); ++i
)
5675 const GUID
*subtype
= &expected_input_types
[i
].subtype
;
5676 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_WMV2
)
5677 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WMVA
)
5678 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVP2
)
5679 || IsEqualGUID(subtype
, &MEDIASUBTYPE_WVC1
)
5680 || IsEqualGUID(subtype
, &MFVideoFormat_VC1S
))
5682 skip("Skipping SetInputType tests for video subtype %s.\n", debugstr_guid(subtype
));
5686 winetest_push_context("in %lu", i
);
5687 check_dmo_set_input_type(media_object
, subtype
);
5688 winetest_pop_context();
5691 /* Test GetOutputType without setting input type. */
5692 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5693 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5694 hr
= IMediaObject_GetOutputType(media_object
, 0, 0, &media_type
);
5695 ok(hr
== DMO_E_TYPE_NOT_SET
, "GetOutputType returned %#lx.\n", hr
);
5697 /* Test GetOutputType after setting input type. */
5698 init_dmo_media_type_video(type
, &expected_input_types
[0].subtype
, 16, 16);
5699 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5700 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5701 check_dmo_get_output_type(media_object
, expected_output_types
, ARRAY_SIZE(expected_output_types
));
5703 /* Test SetOutputType without setting input type. */
5704 hr
= IMediaObject_SetInputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5705 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5706 hr
= IMediaObject_SetOutputType(media_object
, 0, &media_type
, 0);
5707 ok(hr
== DMO_E_TYPE_NOT_SET
, "SetOutputType returned %#lx.\n", hr
);
5709 /* Test SetOutputType after setting input type. */
5710 init_dmo_media_type_video(type
, &expected_input_types
[0].subtype
, 16, 16);
5711 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5712 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5713 check_dmo_set_output_type(media_object
, &MEDIASUBTYPE_RGB24
);
5715 /* Test GetOutputSizeInfo. */
5716 hr
= IMediaObject_SetOutputType(media_object
, 0, NULL
, DMO_SET_TYPEF_CLEAR
);
5717 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5718 hr
= IMediaObject_GetOutputSizeInfo(media_object
, 0, &size
, &alignment
);
5719 ok(hr
== DMO_E_TYPE_NOT_SET
, "GetOutputSizeInfo returned %#lx.\n", hr
);
5721 for (i
= 0; i
< ARRAY_SIZE(expected_output_types
); ++i
)
5723 const GUID
*subtype
= &expected_output_types
[i
].subtype
;
5724 if (IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB565
)
5725 || IsEqualGUID(subtype
, &MEDIASUBTYPE_RGB8
))
5727 skip("Skipping GetOutputSizeInfo tests for video subtype %s.\n", debugstr_guid(subtype
));
5731 winetest_push_context("out %lu", i
);
5732 for (j
= 0; j
< ARRAY_SIZE(test_size
); ++j
)
5734 init_dmo_media_type_video(type
, &expected_output_types
[i
].subtype
, test_size
[j
].x
, test_size
[j
].y
);
5735 hr
= IMediaObject_SetOutputType(media_object
, 0, type
, 0);
5736 todo_wine_if(IsEqualGUID(subtype
, &MEDIASUBTYPE_NV11
)
5737 || IsEqualGUID(subtype
, &MEDIASUBTYPE_IYUV
))
5738 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5743 alignment
= 0xdeadbeef;
5744 hr
= MFCalculateImageSize(subtype
, test_size
[j
].x
, test_size
[j
].y
, (UINT32
*)&expected_size
);
5745 ok(hr
== S_OK
, "MFCalculateImageSize returned %#lx.\n", hr
);
5747 hr
= IMediaObject_GetOutputSizeInfo(media_object
, 0, &size
, &alignment
);
5748 ok(hr
== S_OK
, "GetOutputSizeInfo returned %#lx.\n", hr
);
5749 ok(size
== expected_size
, "Got unexpected size %lu, expected %lu.\n", size
, expected_size
);
5750 ok(alignment
== 1, "Got unexpected alignment %lu.\n", alignment
);
5752 winetest_pop_context();
5755 /* Test ProcessInput. */
5756 load_resource(L
"wmvencdata.bin", &wmv_data
, &wmv_data_length
);
5757 wmv_data_length
= *((DWORD
*)wmv_data
);
5758 wmv_data
+= sizeof(DWORD
);
5759 hr
= media_buffer_create(wmv_data_length
, &input_media_buffer
);
5760 ok(hr
== S_OK
, "Failed to create input media buffer.\n");
5761 memcpy(input_media_buffer
->data
, wmv_data
, wmv_data_length
);
5762 input_media_buffer
->length
= wmv_data_length
;
5764 init_dmo_media_type_video(type
, &MEDIASUBTYPE_WMV1
, data_width
, data_height
);
5765 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5766 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5767 init_dmo_media_type_video(type
, &MEDIASUBTYPE_NV12
, data_width
, data_height
);
5768 hr
= IMediaObject_SetOutputType(media_object
, 0, type
, 0);
5769 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5771 hr
= IMediaObject_ProcessInput(media_object
, 0, &input_media_buffer
->IMediaBuffer_iface
, 0, 0, 0);
5772 ok(hr
== S_OK
, "ProcessInput returned %#lx.\n", hr
);
5774 /* Test ProcessOutput. */
5775 hr
= IMediaObject_GetOutputSizeInfo(media_object
, 0, &size
, &alignment
);
5776 ok(hr
== S_OK
, "GetOutputSizeInfo returned %#lx.\n", hr
);
5777 hr
= media_buffer_create(size
, &output_media_buffer
);
5778 ok(hr
== S_OK
, "Failed to create output media buffer.\n");
5779 output_data_buffer
.pBuffer
= &output_media_buffer
->IMediaBuffer_iface
;
5780 output_data_buffer
.dwStatus
= 0xdeadbeef;
5781 output_data_buffer
.rtTimestamp
= 0xdeadbeef;
5782 output_data_buffer
.rtTimelength
= 0xdeadbeef;
5783 hr
= IMediaObject_ProcessOutput(media_object
, 0, 1, &output_data_buffer
, &status
);
5784 ok(hr
== S_OK
, "ProcessOutput returned %#lx.\n", hr
);
5785 expected_status
= DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT
| DMO_OUTPUT_DATA_BUFFERF_TIME
| DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH
;
5786 ok(output_data_buffer
.dwStatus
== expected_status
, "Got unexpected dwStatus %#lx.\n", output_data_buffer
.dwStatus
);
5787 diff
= check_dmo_output_data_buffer(&output_data_buffer
, &output_buffer_desc_nv12
, L
"nv12frame.bmp", 0, 0);
5788 ok(diff
== 0, "Got %lu%% diff.\n", diff
);
5790 /* Test GetInputStatus. */
5791 hr
= IMediaObject_GetInputStatus(media_object
, 0xdeadbeef, NULL
);
5792 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputStatus returned %#lx.\n", hr
);
5794 status
= 0xdeadbeef;
5795 hr
= IMediaObject_GetInputStatus(media_object
, 0xdeadbeef, &status
);
5796 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "GetInputStatus returned %#lx.\n", hr
);
5797 ok(status
== 0xdeadbeef, "Unexpected status %#lx.\n", status
);
5799 hr
= IMediaObject_GetInputStatus(media_object
, 0, NULL
);
5800 ok(hr
== E_POINTER
, "GetInputStatus returned %#lx.\n", hr
);
5802 hr
= IMediaObject_GetInputStatus(media_object
, 0, &status
);
5803 ok(hr
== S_OK
, "GetInputStatus returned %#lx.\n", hr
);
5804 ok(status
== DMO_INPUT_STATUSF_ACCEPT_DATA
, "Unexpected status %#lx.\n", status
);
5806 /* Test Discontinuity. */
5807 hr
= IMediaObject_Discontinuity(media_object
, 0xdeadbeef);
5808 ok(hr
== DMO_E_INVALIDSTREAMINDEX
, "Discontinuity returned %#lx.\n", hr
);
5809 hr
= IMediaObject_Discontinuity(media_object
, 0);
5810 ok(hr
== S_OK
, "Discontinuity returned %#lx.\n", hr
);
5811 hr
= IMediaObject_Discontinuity(media_object
, 0);
5812 ok(hr
== S_OK
, "Discontinuity returned %#lx.\n", hr
);
5813 hr
= IMediaObject_GetInputStatus(media_object
, 0, &status
);
5814 ok(hr
== S_OK
, "GetInputStatus returned %#lx.\n", hr
);
5815 ok(status
== DMO_INPUT_STATUSF_ACCEPT_DATA
, "Unexpected status %#lx.\n", status
);
5818 hr
= IMediaObject_ProcessInput(media_object
, 0, &input_media_buffer
->IMediaBuffer_iface
, 0, 0, 0);
5819 ok(hr
== S_OK
, "ProcessInput returned %#lx.\n", hr
);
5820 hr
= IMediaObject_Flush(media_object
);
5822 ok(hr
== S_OK
, "Flush returned %#lx.\n", hr
);
5823 hr
= IMediaObject_Flush(media_object
);
5825 ok(hr
== S_OK
, "Flush returned %#lx.\n", hr
);
5826 output_media_buffer
->length
= 0;
5827 output_data_buffer
.pBuffer
= &output_media_buffer
->IMediaBuffer_iface
;
5828 output_data_buffer
.dwStatus
= 0xdeadbeef;
5829 output_data_buffer
.rtTimestamp
= 0xdeadbeef;
5830 output_data_buffer
.rtTimelength
= 0xdeadbeef;
5831 hr
= IMediaObject_ProcessOutput(media_object
, 0, 1, &output_data_buffer
, &status
);
5833 ok(hr
== S_FALSE
, "ProcessOutput returned %#lx.\n", hr
);
5835 ok(output_media_buffer
->length
== 0, "Unexpected length %#lx.\n", output_media_buffer
->length
);
5837 /* Test ProcessOutput with setting framerate. */
5838 init_dmo_media_type_video(type
, &MEDIASUBTYPE_WMV1
, data_width
, data_height
);
5839 ((VIDEOINFOHEADER
*)type
->pbFormat
)->AvgTimePerFrame
= 100000;
5840 hr
= IMediaObject_SetInputType(media_object
, 0, type
, 0);
5841 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
5842 init_dmo_media_type_video(type
, &MEDIASUBTYPE_NV12
, data_width
, data_height
);
5843 ((VIDEOINFOHEADER
*)type
->pbFormat
)->AvgTimePerFrame
= 200000;
5844 hr
= IMediaObject_SetOutputType(media_object
, 0, type
, 0);
5845 ok(hr
== S_OK
, "SetOutputType returned %#lx.\n", hr
);
5847 hr
= IMediaObject_ProcessInput(media_object
, 0, &input_media_buffer
->IMediaBuffer_iface
, 0, 0, 300000);
5848 ok(hr
== S_OK
, "ProcessInput returned %#lx.\n", hr
);
5850 output_media_buffer
->length
= 0;
5851 output_data_buffer
.pBuffer
= &output_media_buffer
->IMediaBuffer_iface
;
5852 output_data_buffer
.dwStatus
= 0xdeadbeef;
5853 output_data_buffer
.rtTimestamp
= 0xdeadbeef;
5854 output_data_buffer
.rtTimelength
= 0xdeadbeef;
5855 hr
= IMediaObject_ProcessOutput(media_object
, 0, 1, &output_data_buffer
, &status
);
5856 ok(hr
== S_OK
, "ProcessOutput returned %#lx.\n", hr
);
5857 expected_status
= DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT
| DMO_OUTPUT_DATA_BUFFERF_TIME
| DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH
;
5858 ok(output_data_buffer
.dwStatus
== expected_status
, "Got unexpected dwStatus %#lx.\n", output_data_buffer
.dwStatus
);
5859 diff
= check_dmo_output_data_buffer(&output_data_buffer
, &output_buffer_desc_nv12
, L
"nv12frame.bmp", 0, 300000);
5860 ok(diff
== 0, "Got %lu%% diff.\n", diff
);
5862 ret
= IMediaBuffer_Release(&output_media_buffer
->IMediaBuffer_iface
);
5863 ok(ret
== 0, "Release returned %lu\n", ret
);
5864 ret
= IMediaBuffer_Release(&input_media_buffer
->IMediaBuffer_iface
);
5866 ok(ret
== 0, "Release returned %lu\n", ret
);
5868 ret
= IMediaObject_Release(media_object
);
5869 ok(ret
== 0, "Release returned %lu\n", ret
);
5871 winetest_pop_context();
5874 static void test_color_convert(void)
5876 const GUID
*const class_id
= &CLSID_CColorConvertDMO
;
5877 const struct transform_info expect_mft_info
=
5879 .name
= L
"Color Converter MFT",
5880 .major_type
= &MFMediaType_Video
,
5883 {.subtype
= &MFVideoFormat_YV12
},
5884 {.subtype
= &MFVideoFormat_YUY2
},
5885 {.subtype
= &MFVideoFormat_UYVY
},
5886 {.subtype
= &MFVideoFormat_AYUV
},
5887 {.subtype
= &MFVideoFormat_NV12
},
5888 {.subtype
= &DMOVideoFormat_RGB32
},
5889 {.subtype
= &DMOVideoFormat_RGB565
},
5890 {.subtype
= &MFVideoFormat_I420
},
5891 {.subtype
= &MFVideoFormat_IYUV
},
5892 {.subtype
= &MFVideoFormat_YVYU
},
5893 {.subtype
= &DMOVideoFormat_RGB24
},
5894 {.subtype
= &DMOVideoFormat_RGB555
},
5895 {.subtype
= &DMOVideoFormat_RGB8
},
5896 {.subtype
= &MEDIASUBTYPE_V216
},
5897 {.subtype
= &MEDIASUBTYPE_V410
},
5898 {.subtype
= &MFVideoFormat_NV11
},
5899 {.subtype
= &MFVideoFormat_Y41P
},
5900 {.subtype
= &MFVideoFormat_Y41T
},
5901 {.subtype
= &MFVideoFormat_Y42T
},
5902 {.subtype
= &MFVideoFormat_YVU9
},
5906 {.subtype
= &MFVideoFormat_YV12
},
5907 {.subtype
= &MFVideoFormat_YUY2
},
5908 {.subtype
= &MFVideoFormat_UYVY
},
5909 {.subtype
= &MFVideoFormat_AYUV
},
5910 {.subtype
= &MFVideoFormat_NV12
},
5911 {.subtype
= &DMOVideoFormat_RGB32
},
5912 {.subtype
= &DMOVideoFormat_RGB565
},
5913 {.subtype
= &MFVideoFormat_I420
},
5914 {.subtype
= &MFVideoFormat_IYUV
},
5915 {.subtype
= &MFVideoFormat_YVYU
},
5916 {.subtype
= &DMOVideoFormat_RGB24
},
5917 {.subtype
= &DMOVideoFormat_RGB555
},
5918 {.subtype
= &DMOVideoFormat_RGB8
},
5919 {.subtype
= &MEDIASUBTYPE_V216
},
5920 {.subtype
= &MEDIASUBTYPE_V410
},
5921 {.subtype
= &MFVideoFormat_NV11
},
5924 const struct transform_info expect_dmo_info
=
5926 .name
= L
"Color Converter DMO",
5927 .major_type
= &MEDIATYPE_Video
,
5930 {.subtype
= &MEDIASUBTYPE_YV12
},
5931 {.subtype
= &MEDIASUBTYPE_YUY2
},
5932 {.subtype
= &MEDIASUBTYPE_UYVY
},
5933 {.subtype
= &MEDIASUBTYPE_AYUV
},
5934 {.subtype
= &MEDIASUBTYPE_NV12
},
5935 {.subtype
= &MEDIASUBTYPE_RGB32
},
5936 {.subtype
= &MEDIASUBTYPE_RGB565
},
5937 {.subtype
= &MEDIASUBTYPE_I420
},
5938 {.subtype
= &MEDIASUBTYPE_IYUV
},
5939 {.subtype
= &MEDIASUBTYPE_YVYU
},
5940 {.subtype
= &MEDIASUBTYPE_RGB24
},
5941 {.subtype
= &MEDIASUBTYPE_RGB555
},
5942 {.subtype
= &MEDIASUBTYPE_RGB8
},
5943 {.subtype
= &MEDIASUBTYPE_V216
},
5944 {.subtype
= &MEDIASUBTYPE_V410
},
5945 {.subtype
= &MEDIASUBTYPE_NV11
},
5946 {.subtype
= &MEDIASUBTYPE_Y41P
},
5947 {.subtype
= &MEDIASUBTYPE_Y41T
},
5948 {.subtype
= &MEDIASUBTYPE_Y42T
},
5949 {.subtype
= &MEDIASUBTYPE_YVU9
},
5953 {.subtype
= &MEDIASUBTYPE_YV12
},
5954 {.subtype
= &MEDIASUBTYPE_YUY2
},
5955 {.subtype
= &MEDIASUBTYPE_UYVY
},
5956 {.subtype
= &MEDIASUBTYPE_AYUV
},
5957 {.subtype
= &MEDIASUBTYPE_NV12
},
5958 {.subtype
= &MEDIASUBTYPE_RGB32
},
5959 {.subtype
= &MEDIASUBTYPE_RGB565
},
5960 {.subtype
= &MEDIASUBTYPE_I420
},
5961 {.subtype
= &MEDIASUBTYPE_IYUV
},
5962 {.subtype
= &MEDIASUBTYPE_YVYU
},
5963 {.subtype
= &MEDIASUBTYPE_RGB24
},
5964 {.subtype
= &MEDIASUBTYPE_RGB555
},
5965 {.subtype
= &MEDIASUBTYPE_RGB8
},
5966 {.subtype
= &MEDIASUBTYPE_V216
},
5967 {.subtype
= &MEDIASUBTYPE_V410
},
5968 {.subtype
= &MEDIASUBTYPE_NV11
},
5972 static const media_type_desc expect_available_inputs
[20] =
5974 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5975 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5976 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
5977 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
5978 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
5979 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
5980 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
5981 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
5982 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
5983 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
5984 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
5985 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
5986 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
5987 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
5988 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
5989 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
5990 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41P
), },
5991 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y41T
), },
5992 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_Y42T
), },
5993 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVU9
), },
5995 static const media_type_desc expect_available_outputs
[16] =
5997 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YV12
), },
5998 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YUY2
), },
5999 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_UYVY
), },
6000 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_AYUV
), },
6001 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
), },
6002 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
), },
6003 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB565
), },
6004 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_I420
), },
6005 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_IYUV
), },
6006 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_YVYU
), },
6007 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB24
), },
6008 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
), },
6009 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_RGB8
), },
6010 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V216
), },
6011 { ATTR_GUID(MF_MT_SUBTYPE
, MEDIASUBTYPE_V410
), },
6012 { ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV11
), },
6014 static const media_type_desc expect_available_common
=
6016 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6017 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6018 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6021 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
6022 static const DWORD actual_width
= 96, actual_height
= 96;
6023 const struct attribute_desc input_type_desc
[] =
6025 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6026 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
6027 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6028 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6031 const struct attribute_desc output_type_desc
[] =
6033 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6034 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6035 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6038 const struct attribute_desc output_type_desc_negative_stride
[] =
6040 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6041 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6042 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6043 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 4),
6046 const struct attribute_desc output_type_desc_positive_stride
[] =
6048 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6049 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6050 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6051 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
6054 const struct attribute_desc expect_input_type_desc
[] =
6056 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6057 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
),
6058 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6059 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6060 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
),
6061 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 3 / 2),
6062 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6063 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6064 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6067 const struct attribute_desc expect_output_type_desc
[] =
6069 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6070 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
6071 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6072 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
6073 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
6074 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6075 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6076 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6079 const struct attribute_desc expect_output_type_desc_negative_stride
[] =
6081 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6082 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
),
6083 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
),
6084 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 4),
6085 ATTR_UINT32(MF_MT_SAMPLE_SIZE
, actual_width
* actual_height
* 4),
6086 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
6087 ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES
, 1),
6088 ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO
, 1, 1),
6091 const MFT_OUTPUT_STREAM_INFO output_info
=
6093 .cbSize
= actual_width
* actual_height
* 4,
6096 const MFT_INPUT_STREAM_INFO input_info
=
6098 .cbSize
= actual_width
* actual_height
* 3 / 2,
6102 const struct buffer_desc output_buffer_desc
=
6104 .length
= actual_width
* actual_height
* 4,
6105 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.right
= 82, .bottom
= 84},
6107 const struct attribute_desc output_sample_attributes
[] =
6109 ATTR_UINT32(MFSampleExtension_CleanPoint
, 0, .todo
= TRUE
),
6112 const struct sample_desc output_sample_desc
=
6114 .attributes
= output_sample_attributes
,
6115 .sample_time
= 0, .sample_duration
= 10000000,
6116 .buffer_count
= 1, .buffers
= &output_buffer_desc
,
6118 const struct transform_desc
6120 const struct attribute_desc
*output_type_desc
;
6121 const struct attribute_desc
*expect_output_type_desc
;
6122 const WCHAR
*result_bitmap
;
6125 color_conversion_tests
[] =
6130 .output_type_desc
= output_type_desc
,
6131 .expect_output_type_desc
= expect_output_type_desc
,
6132 .result_bitmap
= L
"rgb32frame.bmp",
6133 .delta
= 4, /* Windows return 0, Wine needs 4 */
6137 /* YUV -> RGB (negative stride) */
6138 .output_type_desc
= output_type_desc_negative_stride
,
6139 .expect_output_type_desc
= expect_output_type_desc_negative_stride
,
6140 .result_bitmap
= L
"rgb32frame-flip.bmp",
6145 /* YUV -> RGB (positive stride) */
6146 .output_type_desc
= output_type_desc_positive_stride
,
6147 .expect_output_type_desc
= expect_output_type_desc
,
6148 .result_bitmap
= L
"rgb32frame.bmp",
6149 .delta
= 4, /* Windows return 0, Wine needs 4 */
6154 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
6155 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
6156 IMFSample
*input_sample
, *output_sample
;
6157 IMFCollection
*output_samples
;
6158 DWORD length
, output_status
;
6159 const BYTE
*nv12frame_data
;
6160 ULONG nv12frame_data_len
;
6161 IMFMediaType
*media_type
;
6162 IMFTransform
*transform
;
6166 hr
= CoInitialize(NULL
);
6167 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6169 winetest_push_context("colorconv");
6171 if (!check_mft_enum(MFT_CATEGORY_VIDEO_EFFECT
, &input_type
, &output_type
, class_id
))
6173 check_mft_get_info(class_id
, &expect_mft_info
);
6174 check_dmo_get_info(class_id
, &expect_dmo_info
);
6176 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
6177 &IID_IMFTransform
, (void **)&transform
)))
6180 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6181 check_interface(transform
, &IID_IMediaObject
, TRUE
);
6182 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
6184 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
6186 check_interface(transform
, &IID_IMFRealTimeClient
, TRUE
);
6187 /* check_interface(transform, &IID_IWMColorConvProps, TRUE); */
6189 check_mft_optional_methods(transform
, 1);
6190 check_mft_get_attributes(transform
, NULL
, FALSE
);
6191 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6192 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
6195 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
6197 winetest_push_context("out %lu", i
);
6198 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6199 check_media_type(media_type
, expect_available_common
, -1);
6200 check_media_type(media_type
, expect_available_outputs
[i
], -1);
6201 ret
= IMFMediaType_Release(media_type
);
6202 ok(ret
== 0, "Release returned %lu\n", ret
);
6203 winetest_pop_context();
6205 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6206 ok(i
== 16, "%lu output media types\n", i
);
6209 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6211 winetest_push_context("in %lu", i
);
6212 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6213 check_media_type(media_type
, expect_available_common
, -1);
6214 check_media_type(media_type
, expect_available_inputs
[i
], -1);
6215 ret
= IMFMediaType_Release(media_type
);
6216 ok(ret
== 0, "Release returned %lu\n", ret
);
6217 winetest_pop_context();
6219 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6220 ok(i
== 20, "%lu input media types\n", i
);
6222 check_mft_set_input_type_required(transform
, input_type_desc
);
6223 check_mft_set_input_type(transform
, input_type_desc
);
6224 check_mft_get_input_current_type_(transform
, expect_input_type_desc
, FALSE
, TRUE
);
6226 for (i
= 0; i
< ARRAY_SIZE(color_conversion_tests
); i
++)
6228 winetest_push_context("color conversion #%lu", i
);
6229 check_mft_set_output_type_required(transform
, color_conversion_tests
[i
].output_type_desc
);
6230 check_mft_set_output_type(transform
, color_conversion_tests
[i
].output_type_desc
, S_OK
);
6231 check_mft_get_output_current_type_(transform
, color_conversion_tests
[i
].expect_output_type_desc
, FALSE
, TRUE
);
6233 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6234 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6236 load_resource(L
"nv12frame.bmp", &nv12frame_data
, &nv12frame_data_len
);
6237 /* skip BMP header and RGB data from the dump */
6238 length
= *(DWORD
*)(nv12frame_data
+ 2);
6239 nv12frame_data_len
= nv12frame_data_len
- length
;
6240 nv12frame_data
= nv12frame_data
+ length
;
6241 ok(nv12frame_data_len
== 13824, "got length %lu\n", nv12frame_data_len
);
6243 input_sample
= create_sample(nv12frame_data
, nv12frame_data_len
);
6244 hr
= IMFSample_SetSampleTime(input_sample
, 0);
6245 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
6246 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
6247 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
6248 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6249 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
6250 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6251 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
6252 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
6253 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
6254 ret
= IMFSample_Release(input_sample
);
6255 ok(ret
<= 1, "Release returned %ld\n", ret
);
6257 hr
= MFCreateCollection(&output_samples
);
6258 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
6260 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6261 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6262 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
6263 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6264 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
6265 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
6266 ref
= IMFSample_Release(output_sample
);
6267 ok(ref
== 1, "Release returned %ld\n", ref
);
6269 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc
, color_conversion_tests
[i
].result_bitmap
);
6270 ok(ret
<= color_conversion_tests
[i
].delta
, "got %lu%% diff\n", ret
);
6271 IMFCollection_Release(output_samples
);
6273 output_sample
= create_sample(NULL
, output_info
.cbSize
);
6274 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6275 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
6276 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
6277 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
6278 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
6279 ok(length
== 0, "got length %lu\n", length
);
6280 ret
= IMFSample_Release(output_sample
);
6281 ok(ret
== 0, "Release returned %lu\n", ret
);
6282 winetest_pop_context();
6285 ret
= IMFTransform_Release(transform
);
6286 ok(ret
== 0, "Release returned %ld\n", ret
);
6289 winetest_pop_context();
6293 static void test_video_processor(void)
6295 const GUID
*const class_id
= &CLSID_VideoProcessorMFT
;
6296 const struct transform_info expect_mft_info
=
6298 .name
= L
"Microsoft Video Processor MFT",
6299 .major_type
= &MFMediaType_Video
,
6302 {.subtype
= &MFVideoFormat_IYUV
},
6303 {.subtype
= &MFVideoFormat_YV12
},
6304 {.subtype
= &MFVideoFormat_NV12
},
6305 {.subtype
= &MFVideoFormat_YUY2
},
6306 {.subtype
= &MFVideoFormat_ARGB32
},
6307 {.subtype
= &MFVideoFormat_RGB32
},
6308 {.subtype
= &MFVideoFormat_NV11
},
6309 {.subtype
= &MFVideoFormat_AYUV
},
6310 {.subtype
= &MFVideoFormat_UYVY
},
6311 {.subtype
= &MEDIASUBTYPE_P208
},
6312 {.subtype
= &MFVideoFormat_RGB24
},
6313 {.subtype
= &MFVideoFormat_RGB555
},
6314 {.subtype
= &MFVideoFormat_RGB565
},
6315 {.subtype
= &MFVideoFormat_RGB8
},
6316 {.subtype
= &MFVideoFormat_I420
},
6317 {.subtype
= &MFVideoFormat_Y216
},
6318 {.subtype
= &MFVideoFormat_v410
},
6319 {.subtype
= &MFVideoFormat_Y41P
},
6320 {.subtype
= &MFVideoFormat_Y41T
},
6321 {.subtype
= &MFVideoFormat_Y42T
},
6322 {.subtype
= &MFVideoFormat_YVYU
},
6323 {.subtype
= &MFVideoFormat_420O
},
6327 {.subtype
= &MFVideoFormat_IYUV
},
6328 {.subtype
= &MFVideoFormat_YV12
},
6329 {.subtype
= &MFVideoFormat_NV12
},
6330 {.subtype
= &MFVideoFormat_YUY2
},
6331 {.subtype
= &MFVideoFormat_ARGB32
},
6332 {.subtype
= &MFVideoFormat_RGB32
},
6333 {.subtype
= &MFVideoFormat_NV11
},
6334 {.subtype
= &MFVideoFormat_AYUV
},
6335 {.subtype
= &MFVideoFormat_UYVY
},
6336 {.subtype
= &MEDIASUBTYPE_P208
},
6337 {.subtype
= &MFVideoFormat_RGB24
},
6338 {.subtype
= &MFVideoFormat_RGB555
},
6339 {.subtype
= &MFVideoFormat_RGB565
},
6340 {.subtype
= &MFVideoFormat_RGB8
},
6341 {.subtype
= &MFVideoFormat_I420
},
6342 {.subtype
= &MFVideoFormat_Y216
},
6343 {.subtype
= &MFVideoFormat_v410
},
6344 {.subtype
= &MFVideoFormat_Y41P
},
6345 {.subtype
= &MFVideoFormat_Y41T
},
6346 {.subtype
= &MFVideoFormat_Y42T
},
6347 {.subtype
= &MFVideoFormat_YVYU
},
6350 const struct input_type_desc
6355 expect_available_inputs
[] =
6357 {MFVideoFormat_L8
, .optional
= TRUE
/* >= W10 */},
6358 {MFVideoFormat_L16
, .optional
= TRUE
/* >= W10 */},
6359 {MFAudioFormat_MPEG
, .optional
= TRUE
/* >= W10 */},
6360 {MFVideoFormat_IYUV
},
6361 {MFVideoFormat_YV12
},
6362 {MFVideoFormat_NV12
},
6363 {MFVideoFormat_NV21
, .optional
= TRUE
/* >= W11 */},
6364 {MFVideoFormat_420O
},
6365 {MFVideoFormat_P010
, .optional
= TRUE
/* >= W10 */},
6366 {MFVideoFormat_P016
, .optional
= TRUE
/* >= W10 */},
6367 {MFVideoFormat_UYVY
},
6368 {MFVideoFormat_YUY2
},
6369 {MFVideoFormat_P208
},
6370 {MFVideoFormat_NV11
},
6371 {MFVideoFormat_AYUV
},
6372 {MFVideoFormat_ARGB32
},
6373 {MFVideoFormat_ABGR32
, .optional
= TRUE
/* >= W10 */},
6374 {MFVideoFormat_RGB32
},
6375 {MFVideoFormat_A2R10G10B10
, .optional
= TRUE
/* >= W10 */},
6376 {MFVideoFormat_A16B16G16R16F
, .optional
= TRUE
/* >= W10 */},
6377 {MFVideoFormat_RGB24
},
6378 {MFVideoFormat_I420
},
6379 {MFVideoFormat_YVYU
},
6380 {MFVideoFormat_RGB555
},
6381 {MFVideoFormat_RGB565
},
6382 {MFVideoFormat_RGB8
},
6383 {MFVideoFormat_Y216
},
6384 {MFVideoFormat_v410
},
6385 {MFVideoFormat_Y41P
},
6386 {MFVideoFormat_Y41T
},
6387 {MFVideoFormat_Y42T
},
6389 const GUID expect_available_outputs
[] =
6391 MFVideoFormat_A2R10G10B10
, /* enumerated with MFVideoFormat_P010 input */
6392 MFVideoFormat_P010
, /* enumerated with MFVideoFormat_A2R10G10B10 input */
6397 MFVideoFormat_RGB24
,
6398 MFVideoFormat_ARGB32
,
6399 MFVideoFormat_RGB32
,
6401 MFVideoFormat_Y216
, /* enumerated with some input formats */
6402 MFVideoFormat_UYVY
, /* enumerated with some input formats */
6403 MFVideoFormat_YVYU
, /* enumerated with some input formats */
6405 MFVideoFormat_RGB555
,
6406 MFVideoFormat_RGB565
,
6407 MFVideoFormat_AYUV
, /* some inputs enumerate MFVideoFormat_AYUV after RGB565 */
6408 MFVideoFormat_NV12
, /* P010 enumerates NV12 after (A)RGB32 formats */
6409 MFVideoFormat_A16B16G16R16F
, /* enumerated with MFVideoFormat_P010 input */
6410 MFVideoFormat_NV21
, /* enumerated with some input formats */
6412 static const media_type_desc expect_available_common
=
6414 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
),
6416 static const struct attribute_desc expect_transform_attributes
[] =
6418 ATTR_UINT32(MFT_SUPPORT_3DVIDEO
, 1, .todo
= TRUE
),
6419 /* ATTR_UINT32(MF_SA_D3D_AWARE, 1), only on W7 */
6423 static const MFVideoArea actual_aperture
= {.Area
={82,84}};
6424 static const DWORD actual_width
= 96, actual_height
= 96;
6425 const struct attribute_desc rgb32_with_aperture
[] =
6427 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6428 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6429 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6430 ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE
, &actual_aperture
, 16),
6433 const struct attribute_desc nv12_default_stride
[] =
6435 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6436 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_NV12
, .required
= TRUE
),
6437 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6440 const struct attribute_desc rgb32_default_stride
[] =
6442 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6443 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6444 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6447 const struct attribute_desc rgb32_negative_stride
[] =
6449 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6450 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6451 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6452 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 4),
6455 const struct attribute_desc rgb32_positive_stride
[] =
6457 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6458 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB32
, .required
= TRUE
),
6459 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6460 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 4),
6463 const struct attribute_desc rgb555_default_stride
[] =
6465 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6466 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
, .required
= TRUE
),
6467 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6470 const struct attribute_desc rgb555_negative_stride
[] =
6472 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6473 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
, .required
= TRUE
),
6474 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6475 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, -actual_width
* 2),
6478 const struct attribute_desc rgb555_positive_stride
[] =
6480 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Video
, .required
= TRUE
),
6481 ATTR_GUID(MF_MT_SUBTYPE
, MFVideoFormat_RGB555
, .required
= TRUE
),
6482 ATTR_RATIO(MF_MT_FRAME_SIZE
, actual_width
, actual_height
, .required
= TRUE
),
6483 ATTR_UINT32(MF_MT_DEFAULT_STRIDE
, actual_width
* 2),
6486 const MFT_OUTPUT_STREAM_INFO initial_output_info
= {0};
6487 const MFT_INPUT_STREAM_INFO initial_input_info
= {0};
6488 MFT_OUTPUT_STREAM_INFO output_info
= {0};
6489 MFT_INPUT_STREAM_INFO input_info
= {0};
6491 const struct attribute_desc output_sample_attributes
[] =
6493 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1, .todo
= TRUE
),
6496 const struct buffer_desc rgb32_buffer_desc
=
6498 .length
= actual_width
* actual_height
* 4,
6499 .compare
= compare_rgb32
, .dump
= dump_rgb32
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
6501 const struct sample_desc rgb32_sample_desc
=
6503 .attributes
= output_sample_attributes
,
6504 .sample_time
= 0, .sample_duration
= 10000000,
6505 .buffer_count
= 1, .buffers
= &rgb32_buffer_desc
,
6508 const struct buffer_desc rgb555_buffer_desc
=
6510 .length
= actual_width
* actual_height
* 2,
6511 .compare
= compare_rgb16
, .dump
= dump_rgb16
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
6513 const struct sample_desc rgb555_sample_desc
=
6515 .attributes
= output_sample_attributes
,
6516 .sample_time
= 0, .sample_duration
= 10000000,
6517 .buffer_count
= 1, .buffers
= &rgb555_buffer_desc
,
6520 const struct buffer_desc nv12_buffer_desc
=
6522 .length
= actual_width
* actual_height
* 3 / 2,
6523 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.top
= 12, .right
= 82, .bottom
= 96},
6525 const struct sample_desc nv12_sample_desc
=
6527 .attributes
= output_sample_attributes
,
6528 .sample_time
= 0, .sample_duration
= 10000000,
6529 .buffer_count
= 1, .buffers
= &nv12_buffer_desc
,
6532 const struct transform_desc
6534 const struct attribute_desc
*input_type_desc
;
6535 const struct attribute_desc
*output_type_desc
;
6536 const struct sample_desc
*output_sample_desc
;
6537 const WCHAR
*result_bitmap
;
6541 video_processor_tests
[] =
6544 .input_type_desc
= nv12_default_stride
, .output_type_desc
= rgb32_default_stride
,
6545 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame-flip.bmp",
6546 .delta
= 2, /* Windows returns 0, Wine needs 2 */
6549 .input_type_desc
= nv12_default_stride
, .output_type_desc
= rgb32_negative_stride
,
6550 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame-flip.bmp",
6551 .delta
= 2, /* Windows returns 0, Wine needs 2 */
6554 .input_type_desc
= nv12_default_stride
, .output_type_desc
= rgb32_positive_stride
,
6555 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame.bmp",
6559 .input_type_desc
= rgb32_default_stride
, .output_type_desc
= nv12_default_stride
,
6560 .output_sample_desc
= &nv12_sample_desc
, .result_bitmap
= L
"nv12frame-flip.bmp",
6561 .delta
= 2, /* Windows returns 0, Wine needs 2 */
6564 .input_type_desc
= rgb32_negative_stride
, .output_type_desc
= nv12_default_stride
,
6565 .output_sample_desc
= &nv12_sample_desc
, .result_bitmap
= L
"nv12frame-flip.bmp",
6566 .delta
= 2, /* Windows returns 0, Wine needs 2 */
6569 .input_type_desc
= rgb32_positive_stride
, .output_type_desc
= nv12_default_stride
,
6570 .output_sample_desc
= &nv12_sample_desc
, .result_bitmap
= L
"nv12frame.bmp",
6571 .delta
= 2, /* Windows returns 1, Wine needs 2 */
6574 .input_type_desc
= rgb32_negative_stride
, .output_type_desc
= rgb32_negative_stride
,
6575 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame.bmp",
6578 .input_type_desc
= rgb32_negative_stride
, .output_type_desc
= rgb32_positive_stride
,
6579 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame-flip.bmp",
6580 .delta
= 3, /* Windows returns 3 */
6583 .input_type_desc
= rgb32_positive_stride
, .output_type_desc
= rgb32_negative_stride
,
6584 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame-flip.bmp",
6585 .delta
= 3, /* Windows returns 3 */
6588 .input_type_desc
= rgb32_positive_stride
, .output_type_desc
= rgb32_positive_stride
,
6589 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame.bmp",
6592 .input_type_desc
= rgb32_with_aperture
, .output_type_desc
= rgb32_with_aperture
,
6593 .output_sample_desc
= &rgb32_sample_desc
, .result_bitmap
= L
"rgb32frame.bmp",
6594 .broken
= TRUE
/* old Windows version incorrectly rescale */
6597 .input_type_desc
= rgb32_default_stride
, .output_type_desc
= rgb555_default_stride
,
6598 .output_sample_desc
= &rgb555_sample_desc
, .result_bitmap
= L
"rgb555frame.bmp",
6601 .input_type_desc
= rgb32_default_stride
, .output_type_desc
= rgb555_negative_stride
,
6602 .output_sample_desc
= &rgb555_sample_desc
, .result_bitmap
= L
"rgb555frame.bmp",
6605 .input_type_desc
= rgb32_default_stride
, .output_type_desc
= rgb555_positive_stride
,
6606 .output_sample_desc
= &rgb555_sample_desc
, .result_bitmap
= L
"rgb555frame-flip.bmp",
6607 .delta
= 3, /* Windows returns 0, Wine needs 3 */
6610 .input_type_desc
= rgb555_default_stride
, .output_type_desc
= rgb555_positive_stride
,
6611 .output_sample_desc
= &rgb555_sample_desc
, .result_bitmap
= L
"rgb555frame-flip.bmp",
6612 .delta
= 4, /* Windows returns 0, Wine needs 4 */
6616 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Video
, MFVideoFormat_NV12
};
6617 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Video
, MFVideoFormat_I420
};
6618 const struct input_type_desc
*expect_input
= expect_available_inputs
;
6619 DWORD i
, j
, k
, flags
, length
, output_status
;
6620 IMFSample
*input_sample
, *output_sample
;
6621 IMFMediaType
*media_type
, *media_type2
;
6622 IMFCollection
*output_samples
;
6623 IMFTransform
*transform
;
6624 IMFMediaBuffer
*buffer
;
6625 const BYTE
*input_data
;
6626 ULONG input_data_len
;
6633 hr
= CoInitialize(NULL
);
6634 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
6636 winetest_push_context("videoproc");
6638 if (!check_mft_enum(MFT_CATEGORY_VIDEO_PROCESSOR
, &input_type
, &output_type
, class_id
))
6640 check_mft_get_info(class_id
, &expect_mft_info
);
6642 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
6643 &IID_IMFTransform
, (void **)&transform
)))
6647 check_interface(transform
, &IID_IMFVideoProcessorControl
, TRUE
);
6649 check_interface(transform
, &IID_IMFRealTimeClientEx
, TRUE
);
6650 check_interface(transform
, &IID_IMFMediaEventGenerator
, FALSE
);
6651 check_interface(transform
, &IID_IMFShutdown
, FALSE
);
6653 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
6654 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6656 hr
= IMFTransform_GetOutputStatus(transform
, &flags
);
6657 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6659 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6660 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
6662 check_mft_get_input_current_type(transform
, NULL
);
6663 check_mft_get_output_current_type(transform
, NULL
);
6665 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
6666 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
6668 /* Configure stream types. */
6671 if (FAILED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type
)))
6673 ok(hr
== MF_E_NO_MORE_TYPES
, "Unexpected hr %#lx.\n", hr
);
6677 hr
= IMFTransform_GetInputAvailableType(transform
, 0, i
, &media_type2
);
6678 ok(hr
== S_OK
, "Failed to get available type, hr %#lx.\n", hr
);
6679 ok(media_type
!= media_type2
, "Unexpected instance.\n");
6680 ref
= IMFMediaType_Release(media_type2
);
6681 ok(ref
== 0, "Release returned %ld\n", ref
);
6683 hr
= IMFMediaType_GetMajorType(media_type
, &guid
);
6684 ok(hr
== S_OK
, "Failed to get major type, hr %#lx.\n", hr
);
6685 ok(IsEqualGUID(&guid
, &MFMediaType_Video
), "Unexpected major type.\n");
6687 hr
= IMFMediaType_GetCount(media_type
, &count
);
6688 ok(hr
== S_OK
, "Failed to get attributes count, hr %#lx.\n", hr
);
6689 ok(count
== 2, "Unexpected count %u.\n", count
);
6691 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
6692 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
6693 ok(is_supported_video_type(&guid
), "Unexpected media type %s.\n", wine_dbgstr_guid(&guid
));
6695 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
6696 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
6698 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6699 ok(FAILED(hr
), "Unexpected hr %#lx.\n", hr
);
6701 hr
= IMFTransform_GetOutputCurrentType(transform
, 0, &media_type2
);
6702 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "Unexpected hr %#lx.\n", hr
);
6704 /* FIXME: figure out if those require additional attributes or simply advertised but not supported */
6705 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
6706 || IsEqualGUID(&guid
, &MFVideoFormat_D16
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
6707 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
))
6709 ref
= IMFMediaType_Release(media_type
);
6710 ok(ref
== 0, "Release returned %ld\n", ref
);
6714 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
6715 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6717 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, MFT_SET_TYPE_TEST_ONLY
);
6718 ok(hr
== S_OK
, "Failed to test input type %s, hr %#lx.\n", wine_dbgstr_guid(&guid
), hr
);
6720 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6721 ok(hr
== S_OK
, "Failed to test input type, hr %#lx.\n", hr
);
6723 hr
= IMFTransform_GetInputCurrentType(transform
, 0, &media_type2
);
6724 ok(hr
== S_OK
, "Failed to get current type, hr %#lx.\n", hr
);
6725 ok(media_type
!= media_type2
, "Unexpected instance.\n");
6726 IMFMediaType_Release(media_type2
);
6728 hr
= IMFTransform_GetInputStatus(transform
, 0, &flags
);
6729 ok(hr
== S_OK
, "Failed to get input status, hr %#lx.\n", hr
);
6730 ok(flags
== MFT_INPUT_STATUS_ACCEPT_DATA
, "Unexpected input status %#lx.\n", flags
);
6732 input_info
.cbSize
= 0;
6733 if (IsEqualGUID(&guid
, &MFVideoFormat_NV21
))
6734 input_info
.cbSize
= 0x180;
6735 else if (!IsEqualGUID(&guid
, &MFVideoFormat_P208
) && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y41T
)
6736 && !IsEqualGUID(&guid
, &MEDIASUBTYPE_Y42T
))
6738 hr
= MFCalculateImageSize(&guid
, 16, 16, (UINT32
*)&input_info
.cbSize
);
6739 todo_wine_if(IsEqualGUID(&guid
, &MFVideoFormat_Y216
)
6740 || IsEqualGUID(&guid
, &MFVideoFormat_v410
)
6741 || IsEqualGUID(&guid
, &MFVideoFormat_Y41P
))
6742 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6744 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6745 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
6747 IMFMediaType_Release(media_type
);
6751 hr
= MFCreateMediaType(&media_type
);
6752 ok(hr
== S_OK
, "Failed to create media type, hr %#lx.\n", hr
);
6754 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
6755 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6757 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_IYUV
);
6758 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6760 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, ((UINT64
)16 << 32) | 16);
6761 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6763 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6764 ok(hr
== S_OK
, "Failed to set input type, hr %#lx.\n", hr
);
6766 hr
= IMFMediaType_SetGUID(media_type
, &MF_MT_SUBTYPE
, &MFVideoFormat_RGB32
);
6767 ok(hr
== S_OK
, "Failed to set attribute, hr %#lx.\n", hr
);
6769 hr
= IMFTransform_SetOutputType(transform
, 0, media_type
, 0);
6770 ok(hr
== S_OK
, "Failed to set output type, hr %#lx.\n", hr
);
6772 hr
= MFCalculateImageSize(&MFVideoFormat_IYUV
, 16, 16, (UINT32
*)&input_info
.cbSize
);
6773 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6774 hr
= MFCalculateImageSize(&MFVideoFormat_RGB32
, 16, 16, (UINT32
*)&output_info
.cbSize
);
6775 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6776 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6777 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6779 hr
= MFCreateSample(&input_sample
);
6780 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
6782 hr
= MFCreateSample(&output_sample
);
6783 ok(hr
== S_OK
, "Failed to create a sample, hr %#lx.\n", hr
);
6785 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6787 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
6789 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6791 ok(hr
== S_OK
, "Failed to push a sample, hr %#lx.\n", hr
);
6793 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6795 ok(hr
== MF_E_NOTACCEPTING
, "Unexpected hr %#lx.\n", hr
);
6797 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6799 ok(hr
== MF_E_NO_SAMPLE_TIMESTAMP
, "Unexpected hr %#lx.\n", hr
);
6801 hr
= IMFSample_SetSampleTime(input_sample
, 0);
6802 ok(hr
== S_OK
, "Failed to set sample time, hr %#lx.\n", hr
);
6803 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6805 ok(hr
== E_INVALIDARG
, "Unexpected hr %#lx.\n", hr
);
6807 hr
= MFCreateMemoryBuffer(1024 * 1024, &buffer
);
6808 ok(hr
== S_OK
, "Failed to create a buffer, hr %#lx.\n", hr
);
6810 hr
= IMFSample_AddBuffer(input_sample
, buffer
);
6811 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
6813 hr
= IMFSample_AddBuffer(output_sample
, buffer
);
6814 ok(hr
== S_OK
, "Failed to add a buffer, hr %#lx.\n", hr
);
6816 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6818 ok(hr
== S_OK
|| broken(FAILED(hr
)) /* Win8 */, "Failed to get output buffer, hr %#lx.\n", hr
);
6822 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
6823 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "Unexpected hr %#lx.\n", hr
);
6826 ref
= IMFTransform_Release(transform
);
6827 ok(ref
== 0, "Release returned %ld\n", ref
);
6829 ref
= IMFMediaType_Release(media_type
);
6830 ok(ref
== 0, "Release returned %ld\n", ref
);
6831 ref
= IMFSample_Release(input_sample
);
6832 ok(ref
== 0, "Release returned %ld\n", ref
);
6833 ref
= IMFSample_Release(output_sample
);
6834 ok(ref
== 0, "Release returned %ld\n", ref
);
6835 ref
= IMFMediaBuffer_Release(buffer
);
6836 ok(ref
== 0, "Release returned %ld\n", ref
);
6839 hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IMFTransform
, (void **)&transform
);
6840 ok(hr
== S_OK
, "Unexpected hr %#lx.\n", hr
);
6842 check_interface(transform
, &IID_IMFTransform
, TRUE
);
6843 check_interface(transform
, &IID_IMediaObject
, FALSE
);
6844 check_interface(transform
, &IID_IPropertyStore
, FALSE
);
6845 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
6847 check_mft_optional_methods(transform
, 1);
6848 check_mft_get_attributes(transform
, expect_transform_attributes
, TRUE
);
6849 check_mft_get_input_stream_info(transform
, S_OK
, &initial_input_info
);
6850 check_mft_get_output_stream_info(transform
, S_OK
, &initial_output_info
);
6852 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
6853 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6856 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
6858 winetest_push_context("in %lu", i
);
6860 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
6861 check_media_type(media_type
, expect_available_common
, -1);
6863 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
6864 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
6866 while (!IsEqualGUID(&expect_input
->guid
, &guid
))
6868 if (!expect_input
->optional
)
6872 ok(IsEqualGUID(&expect_input
->guid
, &guid
), "got subtype %s\n", debugstr_guid(&guid
));
6875 /* FIXME: Skip exotic input types which aren't directly accepted */
6876 if (IsEqualGUID(&guid
, &MFVideoFormat_L8
) || IsEqualGUID(&guid
, &MFVideoFormat_L16
)
6877 || IsEqualGUID(&guid
, &MFAudioFormat_MPEG
) || IsEqualGUID(&guid
, &MFVideoFormat_420O
)
6878 || IsEqualGUID(&guid
, &MFVideoFormat_A16B16G16R16F
) /* w1064v1507 */)
6880 IMFMediaType_Release(media_type
);
6881 winetest_pop_context();
6885 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6886 ok(hr
== MF_E_ATTRIBUTENOTFOUND
, "SetInputType returned %#lx.\n", hr
);
6887 hr
= IMFMediaType_SetUINT64(media_type
, &MF_MT_FRAME_SIZE
, (UINT64
)actual_width
<< 32 | actual_height
);
6888 ok(hr
== S_OK
, "SetUINT64 returned %#lx.\n", hr
);
6889 hr
= IMFTransform_SetInputType(transform
, 0, media_type
, 0);
6890 ok(hr
== S_OK
, "SetInputType returned %#lx.\n", hr
);
6892 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type2
);
6893 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx.\n", hr
);
6894 hr
= IMFMediaType_IsEqual(media_type
, media_type2
, &flags
);
6895 ok(hr
== S_OK
, "IsEqual returned %#lx.\n", hr
);
6896 IMFMediaType_Release(media_type2
);
6898 ret
= IMFMediaType_Release(media_type
);
6899 ok(ret
== 1, "Release returned %lu\n", ret
);
6902 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++j
, &media_type
)))
6904 winetest_push_context("out %lu", j
);
6905 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
6906 check_media_type(media_type
, expect_available_common
, -1);
6908 hr
= IMFMediaType_GetGUID(media_type
, &MF_MT_SUBTYPE
, &guid
);
6909 ok(hr
== S_OK
, "GetGUID returned %#lx\n", hr
);
6911 for (; k
< ARRAY_SIZE(expect_available_outputs
); k
++)
6912 if (IsEqualGUID(&expect_available_outputs
[k
], &guid
))
6914 ok(k
< ARRAY_SIZE(expect_available_outputs
), "got subtype %s\n", debugstr_guid(&guid
));
6916 ret
= IMFMediaType_Release(media_type
);
6917 ok(ret
== 0, "Release returned %lu\n", ret
);
6918 winetest_pop_context();
6920 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
6922 winetest_pop_context();
6924 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
6926 for (i
= 0; i
< ARRAY_SIZE(video_processor_tests
); i
++)
6928 const struct transform_desc
*test
= video_processor_tests
+ i
;
6930 winetest_push_context("transform #%lu", i
);
6932 check_mft_set_input_type_required(transform
, test
->input_type_desc
);
6933 check_mft_set_input_type(transform
, test
->input_type_desc
);
6934 check_mft_get_input_current_type(transform
, test
->input_type_desc
);
6936 check_mft_set_output_type_required(transform
, test
->output_type_desc
);
6937 check_mft_set_output_type(transform
, test
->output_type_desc
, S_OK
);
6938 check_mft_get_output_current_type(transform
, test
->output_type_desc
);
6940 if (test
->output_sample_desc
== &nv12_sample_desc
)
6942 output_info
.cbSize
= actual_width
* actual_height
* 3 / 2;
6943 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6945 else if (test
->output_sample_desc
== &rgb555_sample_desc
)
6947 output_info
.cbSize
= actual_width
* actual_height
* 2;
6948 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6952 output_info
.cbSize
= actual_width
* actual_height
* 4;
6953 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
6956 if (test
->input_type_desc
== nv12_default_stride
)
6958 input_info
.cbSize
= actual_width
* actual_height
* 3 / 2;
6959 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6961 load_resource(L
"nv12frame.bmp", &input_data
, &input_data_len
);
6962 /* skip BMP header and RGB data from the dump */
6963 length
= *(DWORD
*)(input_data
+ 2);
6964 input_data_len
= input_data_len
- length
;
6965 ok(input_data_len
== 13824, "got length %lu\n", input_data_len
);
6966 input_data
= input_data
+ length
;
6968 else if (test
->input_type_desc
== rgb555_default_stride
)
6970 input_info
.cbSize
= actual_width
* actual_height
* 2;
6971 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6973 load_resource(L
"rgb555frame.bmp", &input_data
, &input_data_len
);
6974 /* skip BMP header and RGB data from the dump */
6975 length
= *(DWORD
*)(input_data
+ 2 + 2 * sizeof(DWORD
));
6976 input_data_len
-= length
;
6977 ok(input_data_len
== 18432, "got length %lu\n", input_data_len
);
6978 input_data
+= length
;
6982 input_info
.cbSize
= actual_width
* actual_height
* 4;
6983 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
6985 load_resource(L
"rgb32frame.bmp", &input_data
, &input_data_len
);
6986 /* skip BMP header and RGB data from the dump */
6987 length
= *(DWORD
*)(input_data
+ 2 + 2 * sizeof(DWORD
));
6988 input_data_len
-= length
;
6989 ok(input_data_len
== 36864, "got length %lu\n", input_data_len
);
6990 input_data
+= length
;
6993 input_sample
= create_sample(input_data
, input_data_len
);
6994 hr
= IMFSample_SetSampleTime(input_sample
, 0);
6995 ok(hr
== S_OK
, "SetSampleTime returned %#lx\n", hr
);
6996 hr
= IMFSample_SetSampleDuration(input_sample
, 10000000);
6997 ok(hr
== S_OK
, "SetSampleDuration returned %#lx\n", hr
);
6998 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
6999 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7000 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
7001 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
7002 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
7003 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
7004 ret
= IMFSample_Release(input_sample
);
7005 ok(ret
<= 1, "Release returned %ld\n", ret
);
7007 hr
= MFCreateCollection(&output_samples
);
7008 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
7010 output_sample
= create_sample(NULL
, output_info
.cbSize
);
7011 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
7013 ok(hr
== S_OK
|| broken(hr
== MF_E_SHUTDOWN
) /* w8 */, "ProcessOutput returned %#lx\n", hr
);
7016 win_skip("ProcessOutput returned MF_E_SHUTDOWN, skipping tests.\n");
7020 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
7022 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
7023 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
7024 ref
= IMFSample_Release(output_sample
);
7025 ok(ref
== 1, "Release returned %ld\n", ref
);
7027 ret
= check_mf_sample_collection(output_samples
, test
->output_sample_desc
, test
->result_bitmap
);
7028 ok(ret
<= test
->delta
|| broken(test
->broken
), "got %lu%% diff\n", ret
);
7029 IMFCollection_Release(output_samples
);
7031 output_sample
= create_sample(NULL
, output_info
.cbSize
);
7032 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
7033 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7034 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
7035 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
7036 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7037 ok(length
== 0, "got length %lu\n", length
);
7039 ret
= IMFSample_Release(output_sample
);
7040 ok(ret
== 0, "Release returned %lu\n", ret
);
7041 winetest_pop_context();
7044 ret
= IMFTransform_Release(transform
);
7045 ok(ret
== 0, "Release returned %ld\n", ret
);
7048 winetest_pop_context();
7052 static void test_mp3_decoder(void)
7054 const GUID
*const class_id
= &CLSID_CMP3DecMediaObject
;
7055 const struct transform_info expect_mft_info
=
7057 .name
= L
"MP3 Decoder MFT",
7058 .major_type
= &MFMediaType_Audio
,
7061 {.subtype
= &MFAudioFormat_MP3
},
7065 {.subtype
= &MFAudioFormat_PCM
},
7068 const struct transform_info expect_dmo_info
=
7070 .name
= L
"MP3 Decoder DMO",
7071 .major_type
= &MEDIATYPE_Audio
,
7074 {.subtype
= &MFAudioFormat_MP3
},
7078 {.subtype
= &MEDIASUBTYPE_PCM
},
7082 static const ULONG mp3dec_block_size
= 0x1200;
7083 static const media_type_desc expect_available_inputs
[] =
7086 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7087 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
7088 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7091 static const media_type_desc expect_available_outputs
[] =
7094 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7095 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7096 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7097 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7098 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7099 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 176400),
7100 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 8),
7101 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7104 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7105 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7106 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7107 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7108 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7109 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
7110 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7111 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7114 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7115 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7116 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
7117 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7118 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7119 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
7120 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
7121 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7124 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7125 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_Float
),
7126 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 32),
7127 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
7128 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7129 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 88200),
7130 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7131 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7134 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7135 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7136 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7137 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
7138 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7139 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 44100),
7140 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2),
7141 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7144 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7145 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7146 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 8),
7147 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 1),
7148 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7149 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050),
7150 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 1),
7151 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7155 const struct attribute_desc input_type_desc
[] =
7157 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
7158 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
, .required
= TRUE
),
7159 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
7160 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7163 static const struct attribute_desc output_type_desc
[] =
7165 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
, .required
= TRUE
),
7166 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
, .required
= TRUE
),
7167 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2, .required
= TRUE
),
7168 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16, .required
= TRUE
),
7169 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050, .required
= TRUE
),
7170 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 2 * (16 / 8), .required
= TRUE
),
7171 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 2 * (16 / 8) * 22050, .required
= TRUE
),
7174 const struct attribute_desc expect_input_type_desc
[] =
7176 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7177 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_MP3
),
7178 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7179 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7180 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7183 static const struct attribute_desc expect_output_type_desc
[] =
7185 ATTR_GUID(MF_MT_MAJOR_TYPE
, MFMediaType_Audio
),
7186 ATTR_GUID(MF_MT_SUBTYPE
, MFAudioFormat_PCM
),
7187 ATTR_UINT32(MF_MT_AUDIO_BITS_PER_SAMPLE
, 16),
7188 ATTR_UINT32(MF_MT_AUDIO_NUM_CHANNELS
, 2),
7189 ATTR_UINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND
, 22050),
7190 ATTR_UINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT
, 4),
7191 ATTR_UINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND
, 22050 * 4),
7192 ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT
, 1),
7193 ATTR_UINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX
, 1),
7196 const MFT_OUTPUT_STREAM_INFO output_info
=
7198 .cbSize
= mp3dec_block_size
,
7201 const MFT_INPUT_STREAM_INFO input_info
=
7206 const struct buffer_desc output_buffer_desc
[] =
7208 {.length
= 0x9c0, .compare
= compare_pcm16
},
7209 {.length
= mp3dec_block_size
, .compare
= compare_pcm16
},
7211 const struct attribute_desc output_sample_attributes
[] =
7213 ATTR_UINT32(mft_output_sample_incomplete
, 1),
7214 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
7217 const struct sample_desc output_sample_desc
[] =
7220 .attributes
= output_sample_attributes
+ 0,
7221 .sample_time
= 0, .sample_duration
= 282993,
7222 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 0,
7225 .attributes
= output_sample_attributes
+ 0,
7226 .sample_time
= 282993, .sample_duration
= 522449,
7227 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1, .repeat_count
= 18,
7230 .attributes
= output_sample_attributes
+ 1, /* not MFT_OUTPUT_DATA_BUFFER_INCOMPLETE */
7231 .sample_time
= 10209524, .sample_duration
= 522449,
7232 .buffer_count
= 1, .buffers
= output_buffer_desc
+ 1,
7236 MFT_REGISTER_TYPE_INFO output_type
= {MFMediaType_Audio
, MFAudioFormat_PCM
};
7237 MFT_REGISTER_TYPE_INFO input_type
= {MFMediaType_Audio
, MFAudioFormat_MP3
};
7238 IMFSample
*input_sample
, *output_sample
;
7239 IMFCollection
*output_samples
;
7240 DWORD length
, output_status
;
7241 IMFMediaType
*media_type
;
7242 IMFTransform
*transform
;
7243 const BYTE
*mp3enc_data
;
7244 ULONG mp3enc_data_len
;
7248 hr
= CoInitialize(NULL
);
7249 ok(hr
== S_OK
, "Failed to initialize, hr %#lx.\n", hr
);
7251 winetest_push_context("mp3dec");
7253 if (!check_mft_enum(MFT_CATEGORY_AUDIO_DECODER
, &input_type
, &output_type
, class_id
))
7255 check_mft_get_info(class_id
, &expect_mft_info
);
7256 check_dmo_get_info(class_id
, &expect_dmo_info
);
7258 if (FAILED(hr
= CoCreateInstance(class_id
, NULL
, CLSCTX_INPROC_SERVER
,
7259 &IID_IMFTransform
, (void **)&transform
)))
7262 check_interface(transform
, &IID_IMFTransform
, TRUE
);
7263 check_interface(transform
, &IID_IMediaObject
, TRUE
);
7265 check_interface(transform
, &IID_IPropertyStore
, TRUE
);
7266 check_interface(transform
, &IID_IPropertyBag
, FALSE
);
7268 check_mft_optional_methods(transform
, 1);
7269 check_mft_get_attributes(transform
, NULL
, FALSE
);
7270 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
7271 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
7273 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &media_type
);
7274 ok(hr
== MF_E_TRANSFORM_TYPE_NOT_SET
, "GetOutputAvailableType returned %#lx\n", hr
);
7277 while (SUCCEEDED(hr
= IMFTransform_GetInputAvailableType(transform
, 0, ++i
, &media_type
)))
7279 winetest_push_context("in %lu", i
);
7280 ok(hr
== S_OK
, "GetInputAvailableType returned %#lx\n", hr
);
7281 check_media_type(media_type
, expect_available_inputs
[i
], -1);
7282 ret
= IMFMediaType_Release(media_type
);
7283 ok(ret
== 0, "Release returned %lu\n", ret
);
7284 winetest_pop_context();
7287 ok(hr
== MF_E_NO_MORE_TYPES
, "GetInputAvailableType returned %#lx\n", hr
);
7289 ok(i
== ARRAY_SIZE(expect_available_inputs
), "%lu input media types\n", i
);
7291 /* setting output media type first doesn't work */
7292 check_mft_set_output_type(transform
, output_type_desc
, MF_E_TRANSFORM_TYPE_NOT_SET
);
7293 check_mft_get_output_current_type(transform
, NULL
);
7295 check_mft_set_input_type_required(transform
, input_type_desc
);
7296 check_mft_set_input_type(transform
, input_type_desc
);
7297 check_mft_get_input_current_type(transform
, expect_input_type_desc
);
7299 check_mft_get_input_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
7300 check_mft_get_output_stream_info(transform
, MF_E_TRANSFORM_TYPE_NOT_SET
, NULL
);
7302 /* check new output media types */
7305 while (SUCCEEDED(hr
= IMFTransform_GetOutputAvailableType(transform
, 0, ++i
, &media_type
)))
7307 winetest_push_context("out %lu", i
);
7308 ok(hr
== S_OK
, "GetOutputAvailableType returned %#lx\n", hr
);
7309 check_media_type(media_type
, expect_available_outputs
[i
], -1);
7310 ret
= IMFMediaType_Release(media_type
);
7311 ok(ret
== 0, "Release returned %lu\n", ret
);
7312 winetest_pop_context();
7314 ok(hr
== MF_E_NO_MORE_TYPES
, "GetOutputAvailableType returned %#lx\n", hr
);
7315 ok(i
== ARRAY_SIZE(expect_available_outputs
), "%lu output media types\n", i
);
7317 check_mft_set_output_type_required(transform
, output_type_desc
);
7318 check_mft_set_output_type(transform
, output_type_desc
, S_OK
);
7319 check_mft_get_output_current_type(transform
, expect_output_type_desc
);
7321 check_mft_get_input_stream_info(transform
, S_OK
, &input_info
);
7322 check_mft_get_output_stream_info(transform
, S_OK
, &output_info
);
7324 load_resource(L
"mp3encdata.bin", &mp3enc_data
, &mp3enc_data_len
);
7325 ok(mp3enc_data_len
== 6295, "got length %lu\n", mp3enc_data_len
);
7327 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
7328 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
7329 ok(hr
== S_OK
, "ProcessInput returned %#lx\n", hr
);
7330 ret
= IMFSample_Release(input_sample
);
7331 ok(ret
== 1, "Release returned %lu\n", ret
);
7333 input_sample
= create_sample(mp3enc_data
, mp3enc_data_len
);
7334 hr
= IMFTransform_ProcessInput(transform
, 0, input_sample
, 0);
7335 ok(hr
== MF_E_NOTACCEPTING
, "ProcessInput returned %#lx\n", hr
);
7336 ret
= IMFSample_Release(input_sample
);
7337 ok(ret
== 0, "Release returned %lu\n", ret
);
7339 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_COMMAND_DRAIN
, 0);
7340 ok(hr
== S_OK
, "ProcessMessage returned %#lx\n", hr
);
7342 hr
= MFCreateCollection(&output_samples
);
7343 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
7345 /* first sample is broken */
7346 output_sample
= create_sample(NULL
, output_info
.cbSize
);
7347 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
7348 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7349 ok(output_status
== MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
, "got output[0].dwStatus %#lx\n", output_status
);
7350 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
7351 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7352 ok(length
== mp3dec_block_size
/* Win8 */ || length
== 0x9c0 /* Win10 */ || length
== 0x900 /* Win7 */,
7353 "got length %lu\n", length
);
7354 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
7355 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
7356 ref
= IMFSample_Release(output_sample
);
7357 ok(ref
== 1, "Release returned %ld\n", ref
);
7359 output_sample
= create_sample(NULL
, output_info
.cbSize
);
7360 for (i
= 0; SUCCEEDED(hr
= check_mft_process_output(transform
, output_sample
, &output_status
)); i
++)
7362 winetest_push_context("%lu", i
);
7363 ok(hr
== S_OK
, "ProcessOutput returned %#lx\n", hr
);
7364 ok(!(output_status
& ~MFT_OUTPUT_DATA_BUFFER_INCOMPLETE
), "got output[0].dwStatus %#lx\n", output_status
);
7365 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)output_sample
);
7366 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
7367 ref
= IMFSample_Release(output_sample
);
7368 ok(ref
== 1, "Release returned %ld\n", ref
);
7369 output_sample
= create_sample(NULL
, output_info
.cbSize
);
7370 winetest_pop_context();
7372 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7373 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
7374 ret
= IMFSample_Release(output_sample
);
7375 ok(ret
== 0, "Release returned %lu\n", ret
);
7376 ok(i
== 20 || broken(i
== 41) /* Win7 */, "got %lu output samples\n", i
);
7378 if (broken(length
!= 0x9c0))
7379 win_skip("Skipping MP3 decoder output sample checks on Win7 / Win8\n");
7382 ret
= check_mf_sample_collection(output_samples
, output_sample_desc
, L
"mp3decdata.bin");
7383 ok(ret
== 0, "got %lu%% diff\n", ret
);
7385 IMFCollection_Release(output_samples
);
7387 output_sample
= create_sample(NULL
, mp3dec_block_size
);
7388 hr
= check_mft_process_output(transform
, output_sample
, &output_status
);
7389 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "ProcessOutput returned %#lx\n", hr
);
7390 ok(output_status
== 0, "got output[0].dwStatus %#lx\n", output_status
);
7391 hr
= IMFSample_GetTotalLength(output_sample
, &length
);
7392 ok(hr
== S_OK
, "GetTotalLength returned %#lx\n", hr
);
7393 ok(length
== 0, "got length %lu\n", length
);
7394 ret
= IMFSample_Release(output_sample
);
7395 ok(ret
== 0, "Release returned %lu\n", ret
);
7397 ret
= IMFTransform_Release(transform
);
7398 ok(ret
== 0, "Release returned %lu\n", ret
);
7401 winetest_pop_context();
7405 static HRESULT
get_next_h264_output_sample(IMFTransform
*transform
, IMFSample
**input_sample
,
7406 IMFSample
*output_sample
, MFT_OUTPUT_DATA_BUFFER
*output
, const BYTE
**data
, ULONG
*data_len
)
7414 memset(output
, 0, sizeof(*output
));
7415 output
[0].pSample
= output_sample
;
7416 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
7418 ok(output
[0].pSample
== output_sample
, "got %p.\n", output
[0].pSample
);
7419 if (hr
!= MF_E_TRANSFORM_NEED_MORE_INPUT
)
7422 ok(status
== 0, "got output[0].dwStatus %#lx\n", status
);
7423 hr
= IMFTransform_ProcessInput(transform
, 0, *input_sample
, 0);
7424 ok(hr
== S_OK
, "got %#lx\n", hr
);
7425 IMFSample_Release(*input_sample
);
7426 *input_sample
= next_h264_sample(data
, data_len
);
7430 static void test_h264_with_dxgi_manager(void)
7432 static const unsigned int set_width
= 82, set_height
= 84, aligned_width
= 96, aligned_height
= 96;
7433 const struct attribute_desc output_sample_attributes
[] =
7435 ATTR_UINT32(MFSampleExtension_CleanPoint
, 1),
7438 const struct buffer_desc output_buffer_desc_nv12
=
7440 .length
= aligned_width
* aligned_height
* 3 / 2,
7441 .compare
= compare_nv12
, .dump
= dump_nv12
, .rect
= {.top
=0, .left
=0, .right
= set_width
, .bottom
= set_height
},
7443 const struct sample_desc output_sample_desc_nv12
=
7445 .attributes
= output_sample_attributes
,
7446 .sample_time
= 333667, .sample_duration
= 333667,
7447 .buffer_count
= 1, .buffers
= &output_buffer_desc_nv12
,
7450 IMFDXGIDeviceManager
*manager
= NULL
;
7451 IMFTrackedSample
*tracked_sample
;
7452 IMFSample
*input_sample
, *sample
;
7453 MFT_OUTPUT_DATA_BUFFER output
[1];
7454 IMFTransform
*transform
= NULL
;
7455 ID3D11Multithread
*multithread
;
7456 IMFCollection
*output_samples
;
7457 MFT_OUTPUT_STREAM_INFO info
;
7458 IMFDXGIBuffer
*dxgi_buffer
;
7459 unsigned int width
, height
;
7460 D3D11_TEXTURE2D_DESC desc
;
7461 IMFMediaBuffer
*buffer
;
7462 IMFAttributes
*attribs
;
7463 ID3D11Texture2D
*tex2d
;
7464 IMF2DBuffer2
*buffer2d
;
7465 ID3D11Device
*d3d11
;
7478 if (!pMFCreateDXGIDeviceManager
)
7480 win_skip("MFCreateDXGIDeviceManager() is not available, skipping tests.\n");
7484 hr
= D3D11CreateDevice(NULL
, D3D_DRIVER_TYPE_HARDWARE
, NULL
, D3D11_CREATE_DEVICE_VIDEO_SUPPORT
, NULL
, 0,
7485 D3D11_SDK_VERSION
, &d3d11
, NULL
, NULL
);
7488 skip("D3D11 device creation failed, skipping tests.\n");
7492 hr
= MFStartup(MF_VERSION
, 0);
7493 ok(hr
== S_OK
, "got %#lx\n", hr
);
7495 hr
= CoInitialize(NULL
);
7496 ok(hr
== S_OK
, "got %#lx\n", hr
);
7498 hr
= ID3D11Device_QueryInterface(d3d11
, &IID_ID3D11Multithread
, (void **)&multithread
);
7499 ok(hr
== S_OK
, "got %#lx\n", hr
);
7500 ID3D11Multithread_SetMultithreadProtected(multithread
, TRUE
);
7501 ID3D11Multithread_Release(multithread
);
7503 hr
= pMFCreateDXGIDeviceManager(&token
, &manager
);
7504 ok(hr
== S_OK
, "got %#lx\n", hr
);
7505 hr
= IMFDXGIDeviceManager_ResetDevice(manager
, (IUnknown
*)d3d11
, token
);
7506 ok(hr
== S_OK
, "got %#lx\n", hr
);
7507 ID3D11Device_Release(d3d11
);
7509 if (FAILED(hr
= CoCreateInstance(&CLSID_MSH264DecoderMFT
, NULL
, CLSCTX_INPROC_SERVER
,
7510 &IID_IMFTransform
, (void **)&transform
)))
7513 hr
= IMFTransform_GetAttributes(transform
, &attribs
);
7514 ok(hr
== S_OK
, "got %#lx\n", hr
);
7516 hr
= IMFAttributes_GetUINT32(attribs
, &MF_SA_D3D11_AWARE
, &value
);
7517 ok(hr
== S_OK
, "got %#lx\n", hr
);
7518 ok(value
== 1, "got %u.\n", value
);
7519 IMFAttributes_Release(attribs
);
7521 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_SET_D3D_MANAGER
, (ULONG_PTR
)transform
);
7522 ok(hr
== E_NOINTERFACE
, "got %#lx\n", hr
);
7524 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_SET_D3D_MANAGER
, (ULONG_PTR
)manager
);
7525 ok(hr
== S_OK
|| broken(hr
== E_NOINTERFACE
), "got %#lx\n", hr
);
7526 if (hr
== E_NOINTERFACE
)
7528 win_skip("No hardware video decoding support.\n");
7532 hr
= MFCreateMediaType(&type
);
7533 ok(hr
== S_OK
, "got %#lx\n", hr
);
7534 hr
= IMFMediaType_SetGUID(type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
7535 ok(hr
== S_OK
, "got %#lx\n", hr
);
7536 hr
= IMFMediaType_SetGUID(type
, &MF_MT_SUBTYPE
, &MFVideoFormat_H264
);
7537 ok(hr
== S_OK
, "got %#lx\n", hr
);
7538 hr
= IMFMediaType_SetUINT64(type
, &MF_MT_FRAME_SIZE
, 1088 | (1920ull << 32));
7539 ok(hr
== S_OK
, "got %#lx\n", hr
);
7540 hr
= IMFTransform_SetInputType(transform
, 0, type
, 0);
7541 ok(hr
== S_OK
, "got %#lx\n", hr
);
7542 IMFMediaType_Release(type
);
7544 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &type
);
7545 ok(hr
== S_OK
, "got %#lx\n", hr
);
7546 hr
= IMFMediaType_SetGUID(type
, &MF_MT_MAJOR_TYPE
, &MFMediaType_Video
);
7547 ok(hr
== S_OK
, "got %#lx\n", hr
);
7548 hr
= IMFMediaType_SetGUID(type
, &MF_MT_SUBTYPE
, &MFVideoFormat_NV12
);
7549 ok(hr
== S_OK
, "got %#lx\n", hr
);
7550 hr
= IMFTransform_SetOutputType(transform
, 0, type
, 0);
7551 ok(hr
== S_OK
, "got %#lx\n", hr
);
7552 IMFMediaType_Release(type
);
7555 memset(output
, 0, sizeof(output
));
7556 hr
= IMFTransform_ProcessOutput(transform
, 0, 1, output
, &status
);
7557 ok(hr
== MF_E_TRANSFORM_NEED_MORE_INPUT
, "got %#lx\n", hr
);
7559 hr
= IMFTransform_GetAttributes(transform
, &attribs
);
7560 ok(hr
== S_OK
, "got %#lx\n", hr
);
7561 hr
= IMFAttributes_GetUINT32(attribs
, &MF_SA_D3D11_AWARE
, &value
);
7562 ok(hr
== S_OK
, "got %#lx\n", hr
);
7563 ok(value
== 1, "got %u.\n", value
);
7564 IMFAttributes_Release(attribs
);
7566 load_resource(L
"h264data.bin", &data
, &data_len
);
7568 input_sample
= next_h264_sample(&data
, &data_len
);
7569 hr
= get_next_h264_output_sample(transform
, &input_sample
, NULL
, output
, &data
, &data_len
);
7570 ok(hr
== MF_E_TRANSFORM_STREAM_CHANGE
, "got %#lx\n", hr
);
7571 ok(!output
[0].pSample
, "got %p.\n", output
[0].pSample
);
7573 hr
= IMFTransform_GetOutputAvailableType(transform
, 0, 0, &type
);
7574 ok(hr
== S_OK
, "got %#lx\n", hr
);
7575 IMFMediaType_GetUINT64(type
, &MF_MT_FRAME_SIZE
, &frame_size
);
7576 ok(hr
== S_OK
, "got %#lx\n", hr
);
7577 width
= frame_size
>> 32;
7578 height
= frame_size
& 0xffffffff;
7579 ok(width
== aligned_width
, "got %u.\n", width
);
7580 ok(height
== aligned_height
, "got %u.\n", height
);
7581 memset(&area
, 0xcc, sizeof(area
));
7582 hr
= IMFMediaType_GetBlob(type
, &MF_MT_MINIMUM_DISPLAY_APERTURE
, (BYTE
*)&area
, sizeof(area
), NULL
);
7583 ok(hr
== S_OK
, "got %#lx\n", hr
);
7584 ok(!area
.OffsetX
.value
&& !area
.OffsetX
.fract
, "got %d.%d.\n", area
.OffsetX
.value
, area
.OffsetX
.fract
);
7585 ok(!area
.OffsetY
.value
&& !area
.OffsetY
.fract
, "got %d.%d.\n", area
.OffsetY
.value
, area
.OffsetY
.fract
);
7586 ok(area
.Area
.cx
== set_width
, "got %ld.\n", area
.Area
.cx
);
7587 ok(area
.Area
.cy
== set_height
, "got %ld.\n", area
.Area
.cy
);
7589 hr
= IMFMediaType_GetGUID(type
, &MF_MT_SUBTYPE
, &guid
);
7590 ok(hr
== S_OK
, "Failed to get subtype, hr %#lx.\n", hr
);
7591 ok(IsEqualIID(&guid
, &MEDIASUBTYPE_NV12
), "got guid %s.\n", debugstr_guid(&guid
));
7593 hr
= IMFTransform_SetOutputType(transform
, 0, type
, 0);
7594 ok(hr
== S_OK
, "got %#lx\n", hr
);
7595 IMFMediaType_Release(type
);
7597 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
7598 ok(hr
== S_OK
, "got %#lx\n", hr
);
7599 ok(info
.dwFlags
== (MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
7600 | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
), "got %#lx.\n", info
.dwFlags
);
7602 hr
= get_next_h264_output_sample(transform
, &input_sample
, NULL
, output
, &data
, &data_len
);
7603 ok(hr
== S_OK
, "got %#lx\n", hr
);
7604 ok(output
[0].dwStatus
== 0, "got %#lx.\n", status
);
7605 sample
= output
[0].pSample
;
7607 hr
= IMFSample_QueryInterface(sample
, &IID_IMFTrackedSample
, (void **)&tracked_sample
);
7608 ok(hr
== S_OK
, "got %#lx\n", hr
);
7609 IMFTrackedSample_Release(tracked_sample
);
7611 hr
= IMFSample_GetBufferCount(sample
, &val
);
7612 ok(hr
== S_OK
, "got %#lx\n", hr
);
7613 ok(val
== 1, "got %lu.\n", val
);
7614 hr
= IMFSample_GetBufferByIndex(sample
, 0, &buffer
);
7615 ok(hr
== S_OK
, "got %#lx\n", hr
);
7616 hr
= IMFMediaBuffer_QueryInterface(buffer
, &IID_IMFDXGIBuffer
, (void **)&dxgi_buffer
);
7617 ok(hr
== S_OK
, "got %#lx\n", hr
);
7618 hr
= IMFMediaBuffer_QueryInterface(buffer
, &IID_IMF2DBuffer2
, (void **)&buffer2d
);
7619 ok(hr
== S_OK
, "got %#lx\n", hr
);
7621 hr
= IMFDXGIBuffer_GetResource(dxgi_buffer
, &IID_ID3D11Texture2D
, (void **)&tex2d
);
7622 ok(hr
== S_OK
, "got %#lx\n", hr
);
7623 memset(&desc
, 0xcc, sizeof(desc
));
7624 ID3D11Texture2D_GetDesc(tex2d
, &desc
);
7625 ok(desc
.Format
== DXGI_FORMAT_NV12
, "got %u.\n", desc
.Format
);
7626 ok(!desc
.Usage
, "got %u.\n", desc
.Usage
);
7627 todo_wine
ok(desc
.BindFlags
== D3D11_BIND_DECODER
, "got %#x.\n", desc
.BindFlags
);
7628 ok(!desc
.CPUAccessFlags
, "got %#x.\n", desc
.CPUAccessFlags
);
7629 ok(!desc
.MiscFlags
, "got %#x.\n", desc
.MiscFlags
);
7630 ok(desc
.MipLevels
== 1, "git %u.\n", desc
.MipLevels
);
7631 ok(desc
.Width
== aligned_width
, "got %u.\n", desc
.Width
);
7632 ok(desc
.Height
== aligned_height
, "got %u.\n", desc
.Height
);
7634 ID3D11Texture2D_Release(tex2d
);
7635 IMFDXGIBuffer_Release(dxgi_buffer
);
7636 IMF2DBuffer2_Release(buffer2d
);
7637 IMFMediaBuffer_Release(buffer
);
7638 IMFSample_Release(sample
);
7641 hr
= get_next_h264_output_sample(transform
, &input_sample
, NULL
, output
, &data
, &data_len
);
7642 ok(hr
== S_OK
, "got %#lx\n", hr
);
7643 ok(sample
!= output
[0].pSample
, "got %p.\n", output
[0].pSample
);
7644 sample
= output
[0].pSample
;
7646 hr
= MFCreateCollection(&output_samples
);
7647 ok(hr
== S_OK
, "MFCreateCollection returned %#lx\n", hr
);
7649 hr
= IMFCollection_AddElement(output_samples
, (IUnknown
*)sample
);
7650 ok(hr
== S_OK
, "AddElement returned %#lx\n", hr
);
7651 IMFSample_Release(sample
);
7653 ret
= check_mf_sample_collection(output_samples
, &output_sample_desc_nv12
, L
"nv12frame.bmp");
7654 ok(ret
== 0, "got %lu%% diff\n", ret
);
7655 IMFCollection_Release(output_samples
);
7657 memset(&info
, 0xcc, sizeof(info
));
7658 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
7659 ok(hr
== S_OK
, "got %#lx\n", hr
);
7660 ok(info
.dwFlags
== (MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
7661 | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
| MFT_OUTPUT_STREAM_PROVIDES_SAMPLES
), "got %#lx.\n", info
.dwFlags
);
7662 ok(info
.cbSize
== aligned_width
* aligned_height
* 2, "got %lu.\n", info
.cbSize
);
7663 ok(!info
.cbAlignment
, "got %lu.\n", info
.cbAlignment
);
7665 hr
= IMFTransform_ProcessMessage(transform
, MFT_MESSAGE_SET_D3D_MANAGER
, 0);
7666 ok(hr
== S_OK
, "got %#lx\n", hr
);
7668 memset(&info
, 0xcc, sizeof(info
));
7669 hr
= IMFTransform_GetOutputStreamInfo(transform
, 0, &info
);
7670 ok(hr
== S_OK
, "got %#lx\n", hr
);
7671 ok(info
.dwFlags
== (MFT_OUTPUT_STREAM_WHOLE_SAMPLES
| MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER
7672 | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE
), "got %#lx.\n", info
.dwFlags
);
7675 /* hangs on Windows. */
7676 get_next_h264_output_sample(transform
, &input_sample
, NULL
, output
, &data
, &data_len
);
7679 IMFSample_Release(input_sample
);
7683 IMFDXGIDeviceManager_Release(manager
);
7685 IMFTransform_Release(transform
);
7689 static void test_iv50_encoder(void)
7691 static const BITMAPINFOHEADER expect_iv50
=
7693 .biSize
= sizeof(BITMAPINFOHEADER
),
7694 .biWidth
= 0x60, .biHeight
= 0x60,
7695 .biPlanes
= 1, .biBitCount
= 0x18,
7696 .biCompression
= mmioFOURCC('I','V','5','0'),
7697 .biSizeImage
= 0x5100,
7699 const struct buffer_desc iv50_buffer_desc
=
7703 const struct sample_desc iv50_sample_desc
=
7705 .buffer_count
= 1, .buffers
= &iv50_buffer_desc
,
7707 const BYTE
*res_data
;
7708 BYTE rgb_data
[0x6c00], iv50_data
[0x5100];
7709 BITMAPINFO rgb_info
, iv50_info
;
7710 IMFCollection
*collection
;
7711 DWORD flags
, res_len
, ret
;
7717 load_resource(L
"rgb555frame.bmp", (const BYTE
**)&res_data
, &res_len
);
7718 res_data
+= 2 + 3 * sizeof(DWORD
);
7719 res_len
-= 2 + 3 * sizeof(DWORD
);
7720 rgb_info
.bmiHeader
= *(BITMAPINFOHEADER
*)res_data
;
7721 memcpy(rgb_data
, res_data
+ sizeof(BITMAPINFOHEADER
), res_len
- sizeof(BITMAPINFOHEADER
));
7723 hic
= ICOpen(ICTYPE_VIDEO
, expect_iv50
.biCompression
, ICMODE_COMPRESS
);
7727 win_skip("ICOpen failed to created IV50 compressor.\n");
7731 res
= ICCompressQuery(hic
, &rgb_info
, NULL
);
7733 ok(!res
, "got res %#Ix\n", res
);
7737 res
= ICCompressGetSize(hic
, &rgb_info
, NULL
);
7738 ok(res
== expect_iv50
.biSizeImage
, "got res %#Ix\n", res
);
7740 res
= ICCompressGetFormatSize(hic
, &rgb_info
);
7741 ok(res
== sizeof(BITMAPINFOHEADER
), "got res %#Ix\n", res
);
7742 res
= ICCompressGetFormat(hic
, &rgb_info
, &iv50_info
);
7743 ok(!res
, "got res %#Ix\n", res
);
7744 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biSize
);
7745 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biWidth
);
7746 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biHeight
);
7747 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#x", biPlanes
);
7748 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#x", biBitCount
);
7749 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biCompression
);
7750 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biSizeImage
);
7751 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biXPelsPerMeter
);
7752 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biYPelsPerMeter
);
7753 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biClrUsed
);
7754 check_member(iv50_info
.bmiHeader
, expect_iv50
, "%#lx", biClrImportant
);
7755 res
= ICCompressQuery(hic
, &rgb_info
, &iv50_info
);
7756 ok(!res
, "got res %#Ix\n", res
);
7758 res
= ICCompressBegin(hic
, &rgb_info
, &iv50_info
);
7759 ok(!res
, "got res %#Ix\n", res
);
7760 memset(iv50_data
, 0xcd, sizeof(iv50_data
));
7761 res
= ICCompress(hic
, ICCOMPRESS_KEYFRAME
, &iv50_info
.bmiHeader
, iv50_data
, &rgb_info
.bmiHeader
, rgb_data
,
7762 NULL
, &flags
, 1, 0, 0, NULL
, NULL
);
7763 ok(!res
, "got res %#Ix\n", res
);
7764 ok(flags
== 0x10, "got flags %#lx\n", flags
);
7765 ok(iv50_info
.bmiHeader
.biSizeImage
== 0x2e8, "got res %#Ix\n", res
);
7766 res
= ICCompressEnd(hic
);
7767 ok(!res
, "got res %#Ix\n", res
);
7769 hr
= MFCreateCollection(&collection
);
7770 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7771 sample
= create_sample(iv50_data
, iv50_info
.bmiHeader
.biSizeImage
);
7772 ok(!!sample
, "got sample %p\n", sample
);
7773 hr
= IMFSample_SetSampleTime(sample
, 0);
7774 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7775 hr
= IMFSample_SetSampleDuration(sample
, 0);
7776 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7777 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)sample
);
7778 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7779 ret
= check_mf_sample_collection(collection
, &iv50_sample_desc
, L
"iv50frame.bin");
7780 ok(ret
== 0, "got %lu%% diff\n", ret
);
7781 IMFCollection_Release(collection
);
7785 ok(!res
, "got res %#Ix\n", res
);
7788 static void test_iv50_decoder(void)
7790 static const BITMAPINFOHEADER expect_iv50
=
7792 .biSize
= sizeof(BITMAPINFOHEADER
),
7793 .biWidth
= 0x60, .biHeight
= 0x60,
7794 .biPlanes
= 1, .biBitCount
= 24,
7795 .biCompression
= mmioFOURCC('I','V','5','0'),
7796 .biSizeImage
= 0x2e8,
7798 static const BITMAPINFOHEADER expect_rgb
=
7800 .biSize
= sizeof(BITMAPINFOHEADER
),
7801 .biWidth
= 0x60, .biHeight
= 0x60,
7802 .biPlanes
= 1, .biBitCount
= 24,
7803 .biCompression
= BI_RGB
,
7804 .biSizeImage
= 96 * 96 * 3,
7806 const struct buffer_desc rgb_buffer_desc
=
7808 .length
= 96 * 96 * 3, .compare
= compare_rgb24
, .dump
= dump_rgb24
,
7809 .rect
= {.right
= 82, .bottom
= 84},
7811 const struct sample_desc rgb_sample_desc
=
7813 .buffer_count
= 1, .buffers
= &rgb_buffer_desc
,
7815 const BYTE
*res_data
;
7816 BYTE rgb_data
[0x6c00], iv50_data
[0x5100];
7817 BITMAPINFO rgb_info
, iv50_info
;
7818 IMFCollection
*collection
;
7825 load_resource(L
"iv50frame.bin", (const BYTE
**)&res_data
, &res_len
);
7826 memcpy(iv50_data
, res_data
, res_len
);
7828 iv50_info
.bmiHeader
= expect_iv50
;
7829 hic
= ICOpen(ICTYPE_VIDEO
, expect_iv50
.biCompression
, ICMODE_DECOMPRESS
);
7833 win_skip("ICOpen failed to created IV50 decompressor.\n");
7837 res
= ICDecompressGetFormat(hic
, &iv50_info
, &rgb_info
);
7838 ok(!res
, "got res %#Ix\n", res
);
7839 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biSize
);
7840 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biWidth
);
7841 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biHeight
);
7842 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#x", biPlanes
);
7844 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#x", biBitCount
);
7845 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biCompression
);
7847 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biSizeImage
);
7848 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biXPelsPerMeter
);
7849 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biYPelsPerMeter
);
7850 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biClrUsed
);
7851 check_member(rgb_info
.bmiHeader
, expect_rgb
, "%#lx", biClrImportant
);
7852 rgb_info
.bmiHeader
= expect_rgb
;
7854 res
= ICDecompressBegin(hic
, &iv50_info
, &rgb_info
);
7855 ok(!res
, "got res %#Ix\n", res
);
7856 res
= ICDecompress(hic
, 0, &iv50_info
.bmiHeader
, iv50_data
, &rgb_info
.bmiHeader
, rgb_data
);
7857 ok(!res
, "got res %#Ix\n", res
);
7858 res
= ICDecompressEnd(hic
);
7860 ok(!res
, "got res %#Ix\n", res
);
7863 ok(!res
, "got res %#Ix\n", res
);
7866 hr
= MFCreateCollection(&collection
);
7867 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7868 sample
= create_sample(rgb_data
, rgb_info
.bmiHeader
.biSizeImage
);
7869 ok(!!sample
, "got sample %p\n", sample
);
7870 hr
= IMFSample_SetSampleTime(sample
, 0);
7871 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7872 hr
= IMFSample_SetSampleDuration(sample
, 0);
7873 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7874 hr
= IMFCollection_AddElement(collection
, (IUnknown
*)sample
);
7875 ok(hr
== S_OK
, "got hr %#lx\n", hr
);
7876 ret
= check_mf_sample_collection(collection
, &rgb_sample_desc
, L
"rgb24frame.bmp");
7877 ok(ret
<= 4, "got %lu%% diff\n", ret
);
7878 IMFCollection_Release(collection
);
7881 START_TEST(transform
)
7885 test_sample_copier();
7886 test_sample_copier_output_processing();
7891 test_h264_decoder();
7894 test_wmv_decoder_media_object();
7895 test_audio_convert();
7896 test_color_convert();
7897 test_video_processor();
7899 test_iv50_encoder();
7900 test_iv50_decoder();
7902 test_h264_with_dxgi_manager();
7903 test_h264_decoder_concat_streams();