mfplat: Implement IsMediaTypeSupported() for stream descriptor.
[wine.git] / dlls / mfplat / tests / mfplat.c
blob97108e14785df127c964743bd1514471743f6f9c
1 /*
2 * Unit test suite for mfplat.
4 * Copyright 2015 Michael Müller
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "ole2.h"
31 #include "mfapi.h"
32 #include "mfidl.h"
33 #include "mferror.h"
34 #include "mfreadwrite.h"
35 #include "propvarutil.h"
36 #include "strsafe.h"
38 #include "wine/test.h"
39 #include "wine/heap.h"
41 #define D3D11_INIT_GUID
42 #include "initguid.h"
43 #include "d3d11_4.h"
45 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
46 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
47 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
48 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
49 DEFINE_GUID(CLSID_FileSchemeHandler, 0x477ec299, 0x1421, 0x4bdd, 0x97, 0x1f, 0x7c, 0xcb, 0x93, 0x3f, 0x21, 0xad);
51 static BOOL is_win8_plus;
53 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
54 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
56 ULONG rc;
57 IUnknown_AddRef(obj);
58 rc = IUnknown_Release(obj);
59 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
62 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
63 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
64 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
66 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
68 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
69 DWORD width, DWORD lines);
70 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
71 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
72 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
73 static void* (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type);
74 static void (WINAPI *pMFHeapFree)(void *p);
75 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
76 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
77 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
78 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
79 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
80 IMFActivate *activate);
81 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
82 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
83 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
84 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
85 const MFT_REGISTER_TYPE_INFO* output_types);
86 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
87 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
88 const MFT_REGISTER_TYPE_INFO *output_types);
89 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
90 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
91 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
92 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
93 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
94 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
96 static const WCHAR fileschemeW[] = L"file://";
98 static WCHAR *load_resource(const WCHAR *name)
100 static WCHAR pathW[MAX_PATH];
101 DWORD written;
102 HANDLE file;
103 HRSRC res;
104 void *ptr;
106 GetTempPathW(ARRAY_SIZE(pathW), pathW);
107 lstrcatW(pathW, name);
109 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
110 NULL, CREATE_ALWAYS, 0, 0);
111 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
112 wine_dbgstr_w(pathW), GetLastError());
114 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
115 ok(res != 0, "couldn't find resource\n");
116 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
117 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
118 &written, NULL);
119 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
120 "couldn't write resource\n" );
121 CloseHandle(file);
123 return pathW;
126 struct test_callback
128 IMFAsyncCallback IMFAsyncCallback_iface;
129 HANDLE event;
130 DWORD param;
133 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
135 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
138 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
140 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
141 IsEqualIID(riid, &IID_IUnknown))
143 *obj = iface;
144 IMFAsyncCallback_AddRef(iface);
145 return S_OK;
148 *obj = NULL;
149 return E_NOINTERFACE;
152 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
154 return 2;
157 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
159 return 1;
162 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
164 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
165 return E_NOTIMPL;
169 static BOOL check_clsid(CLSID *clsids, UINT32 count)
171 int i;
172 for (i = 0; i < count; i++)
174 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
175 return TRUE;
177 return FALSE;
180 static void test_register(void)
182 WCHAR name[] = L"Wine test";
183 MFT_REGISTER_TYPE_INFO input[] =
185 { DUMMY_CLSID, DUMMY_GUID1 }
187 MFT_REGISTER_TYPE_INFO output[] =
189 { DUMMY_CLSID, DUMMY_GUID2 }
191 CLSID *clsids;
192 UINT32 count;
193 HRESULT ret;
195 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
196 if (ret == E_ACCESSDENIED)
198 win_skip("Not enough permissions to register a filter\n");
199 return;
201 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
203 if(0)
205 /* NULL name crashes on windows */
206 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
207 ok(ret == E_INVALIDARG, "got %x\n", ret);
210 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
211 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
213 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
214 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
216 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
217 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
219 if(0)
221 /* NULL clsids/count crashes on windows (vista) */
222 count = 0;
223 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
224 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
225 ok(count == 0, "Expected count == 0\n");
227 clsids = NULL;
228 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
229 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
232 count = 0;
233 clsids = NULL;
234 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
235 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
236 ok(count > 0, "Expected count > 0\n");
237 ok(clsids != NULL, "Expected clsids != NULL\n");
238 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
239 CoTaskMemFree(clsids);
241 count = 0;
242 clsids = NULL;
243 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
244 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
245 ok(count > 0, "Expected count > 0\n");
246 ok(clsids != NULL, "Expected clsids != NULL\n");
247 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
248 CoTaskMemFree(clsids);
250 count = 0;
251 clsids = NULL;
252 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
253 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
254 ok(count > 0, "Expected count > 0\n");
255 ok(clsids != NULL, "Expected clsids != NULL\n");
256 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
257 CoTaskMemFree(clsids);
259 count = 0;
260 clsids = NULL;
261 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
262 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
263 ok(count > 0, "Expected count > 0\n");
264 ok(clsids != NULL, "Expected clsids != NULL\n");
265 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
266 CoTaskMemFree(clsids);
268 /* exchange input and output */
269 count = 0;
270 clsids = NULL;
271 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
272 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
273 ok(!count, "got %d\n", count);
274 ok(clsids == NULL, "Expected clsids == NULL\n");
276 ret = MFTUnregister(DUMMY_CLSID);
277 ok(ret == S_OK ||
278 /* w7pro64 */
279 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
281 ret = MFTUnregister(DUMMY_CLSID);
282 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
285 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
287 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
288 IMFSourceResolver *resolver;
289 IUnknown *object, *object2;
290 MF_OBJECT_TYPE obj_type;
291 HRESULT hr;
293 ok(!!result, "Unexpected result object.\n");
295 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
297 object = NULL;
298 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
299 todo_wine
300 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
302 hr = IMFAsyncResult_GetObject(result, &object2);
303 ok(hr == S_OK, "Failed to get result object, hr %#x.\n", hr);
304 todo_wine
305 ok(object2 == object, "Unexpected object.\n");
307 if (object)
308 IUnknown_Release(object);
309 IUnknown_Release(object2);
311 SetEvent(callback->event);
313 return S_OK;
316 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
318 testcallback_QueryInterface,
319 testcallback_AddRef,
320 testcallback_Release,
321 testcallback_GetParameters,
322 test_create_from_url_callback_Invoke,
325 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
327 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
328 IMFSchemeHandler *handler;
329 IUnknown *object, *object2;
330 MF_OBJECT_TYPE obj_type;
331 HRESULT hr;
333 ok(!!result, "Unexpected result object.\n");
335 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
337 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
338 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
340 hr = IMFAsyncResult_GetObject(result, &object2);
341 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
343 IUnknown_Release(object);
345 SetEvent(callback->event);
347 return S_OK;
350 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
352 testcallback_QueryInterface,
353 testcallback_AddRef,
354 testcallback_Release,
355 testcallback_GetParameters,
356 test_create_from_file_handler_callback_Invoke,
359 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
361 MediaEventType event_type;
362 HRESULT hr, event_status;
363 IMFMediaEvent *event;
365 hr = IMFMediaEventGenerator_GetEvent(generator, 0, &event);
366 ok(hr == S_OK, "Failed to get event, hr %#x.\n", hr);
368 hr = IMFMediaEvent_GetStatus(event, &event_status);
369 ok(hr == S_OK, "Failed to get status code, hr %#x.\n", hr);
370 ok(event_status == S_OK, "Unexpected event status code %#x.\n", event_status);
372 hr = IMFMediaEvent_GetType(event, &event_type);
373 ok(hr == S_OK, "Failed to event type, hr %#x.\n", hr);
374 ok(event_type == expected_event_type, "Unexpected event type %u, expected %u.\n", event_type, expected_event_type);
376 if (event_type != expected_event_type)
378 IMFMediaEvent_Release(event);
379 return FALSE;
382 if (value)
384 hr = IMFMediaEvent_GetValue(event, value);
385 ok(hr == S_OK, "Failed to get value of event, hr %#x.\n", hr);
388 IMFMediaEvent_Release(event);
390 return TRUE;
393 static void test_source_resolver(void)
395 struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
396 struct test_callback callback2 = { { &test_create_from_file_handler_callback_vtbl } };
397 IMFSourceResolver *resolver, *resolver2;
398 IMFPresentationDescriptor *descriptor;
399 IMFSchemeHandler *scheme_handler;
400 IMFMediaStream *video_stream;
401 IMFAttributes *attributes;
402 IMFMediaSource *mediasource;
403 IMFMediaTypeHandler *handler;
404 IMFMediaType *media_type;
405 BOOL selected, do_uninit;
406 MF_OBJECT_TYPE obj_type;
407 IMFStreamDescriptor *sd;
408 IUnknown *cancel_cookie;
409 IMFByteStream *stream;
410 WCHAR pathW[MAX_PATH];
411 int i, sample_count;
412 WCHAR *filename;
413 PROPVARIANT var;
414 HRESULT hr;
415 GUID guid;
417 if (!pMFCreateSourceResolver)
419 win_skip("MFCreateSourceResolver() not found\n");
420 return;
423 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
424 ok(hr == S_OK, "got 0x%08x\n", hr);
426 hr = pMFCreateSourceResolver(NULL);
427 ok(hr == E_POINTER, "got %#x\n", hr);
429 hr = pMFCreateSourceResolver(&resolver);
430 ok(hr == S_OK, "got %#x\n", hr);
432 hr = pMFCreateSourceResolver(&resolver2);
433 ok(hr == S_OK, "got %#x\n", hr);
434 ok(resolver != resolver2, "Expected new instance\n");
436 IMFSourceResolver_Release(resolver2);
438 filename = load_resource(L"test.mp4");
440 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
441 ok(hr == S_OK, "got 0x%08x\n", hr);
443 hr = IMFSourceResolver_CreateObjectFromByteStream(
444 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
445 &obj_type, (IUnknown **)&mediasource);
446 ok(hr == E_POINTER, "got 0x%08x\n", hr);
448 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
449 NULL, (IUnknown **)&mediasource);
450 ok(hr == E_POINTER, "got 0x%08x\n", hr);
452 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
453 &obj_type, NULL);
454 ok(hr == E_POINTER, "got 0x%08x\n", hr);
456 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
457 &obj_type, (IUnknown **)&mediasource);
458 todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
459 if (hr == S_OK) IMFMediaSource_Release(mediasource);
461 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_BYTESTREAM, NULL,
462 &obj_type, (IUnknown **)&mediasource);
463 todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
465 IMFByteStream_Release(stream);
467 /* We have to create a new bytestream here, because all following
468 * calls to CreateObjectFromByteStream will fail. */
469 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
470 ok(hr == S_OK, "got 0x%08x\n", hr);
472 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
473 ok(hr == S_OK, "got 0x%08x\n", hr);
474 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
475 ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr);
476 IMFAttributes_Release(attributes);
478 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
479 &obj_type, (IUnknown **)&mediasource);
480 ok(hr == S_OK, "got 0x%08x\n", hr);
481 ok(mediasource != NULL, "got %p\n", mediasource);
482 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
484 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
485 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
486 ok(descriptor != NULL, "got %p\n", descriptor);
488 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
489 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
491 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
492 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
493 IMFStreamDescriptor_Release(sd);
495 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
496 todo_wine
497 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
498 if (FAILED(hr))
499 goto skip_source_tests;
501 /* Check major/minor type for the test media. */
502 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
504 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
505 ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
506 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
507 ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
508 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
509 IMFMediaType_Release(media_type);
511 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
512 ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr);
514 var.vt = VT_EMPTY;
515 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
516 ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
518 get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
519 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt);
520 video_stream = (IMFMediaStream *)var.punkVal;
522 get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, NULL);
524 /* Request samples, our file is 10 frames at 25fps */
525 get_event((IMFMediaEventGenerator *)video_stream, MEStreamStarted, NULL);
526 sample_count = 10;
528 /* Request one beyond EOS, otherwise EndOfStream isn't queued. */
529 for (i = 0; i <= sample_count; ++i)
531 hr = IMFMediaStream_RequestSample(video_stream, NULL);
532 if (i == sample_count)
533 break;
534 ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
535 if (hr != S_OK)
536 break;
539 for (i = 0; i < sample_count; ++i)
541 static const LONGLONG MILLI_TO_100_NANO = 10000;
542 LONGLONG duration, time;
543 DWORD buffer_count;
544 IMFSample *sample;
545 BOOL ret;
547 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
548 ok(ret, "Sample %u not received.\n", i + 1);
549 if (!ret)
550 break;
552 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
553 sample = (IMFSample *)var.punkVal;
555 hr = IMFSample_GetBufferCount(sample, &buffer_count);
556 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
557 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
559 hr = IMFSample_GetSampleDuration(sample, &duration);
560 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
561 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
563 hr = IMFSample_GetSampleTime(sample, &time);
564 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
565 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
567 IMFSample_Release(sample);
570 if (i == sample_count)
571 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
573 hr = IMFMediaStream_RequestSample(video_stream, NULL);
574 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
575 IMFMediaStream_Release(video_stream);
577 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
579 IMFMediaTypeHandler_Release(handler);
581 hr = IMFMediaSource_Shutdown(mediasource);
582 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
584 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
585 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
587 skip_source_tests:
589 IMFPresentationDescriptor_Release(descriptor);
590 IMFMediaSource_Release(mediasource);
591 IMFByteStream_Release(stream);
593 /* Create from URL. */
594 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
596 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
597 (IUnknown **)&stream);
598 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
599 IMFByteStream_Release(stream);
601 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
602 &cancel_cookie, &callback.IMFAsyncCallback_iface, (IUnknown *)resolver);
603 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
604 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
605 IUnknown_Release(cancel_cookie);
607 if (SUCCEEDED(hr))
608 WaitForSingleObject(callback.event, INFINITE);
610 /* With explicit scheme. */
611 lstrcpyW(pathW, fileschemeW);
612 lstrcatW(pathW, filename);
614 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
615 (IUnknown **)&stream);
616 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
617 IMFByteStream_Release(stream);
619 IMFSourceResolver_Release(resolver);
621 /* Create directly through scheme handler. */
622 hr = CoInitialize(NULL);
623 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
624 do_uninit = hr == S_OK;
626 hr = CoCreateInstance(&CLSID_FileSchemeHandler, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
627 (void **)&scheme_handler);
628 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
630 callback2.event = callback.event;
631 cancel_cookie = NULL;
632 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
633 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
634 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
635 ok(!!cancel_cookie, "Unexpected cancel object.\n");
636 IUnknown_Release(cancel_cookie);
638 WaitForSingleObject(callback2.event, INFINITE);
640 IMFSchemeHandler_Release(scheme_handler);
642 if (do_uninit)
643 CoUninitialize();
645 hr = MFShutdown();
646 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
648 DeleteFileW(filename);
650 CloseHandle(callback.event);
653 static void init_functions(void)
655 HMODULE mod = GetModuleHandleA("mfplat.dll");
657 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
658 X(MFAddPeriodicCallback);
659 X(MFAllocateSerialWorkQueue);
660 X(MFAllocateWorkQueueEx);
661 X(MFCopyImage);
662 X(MFCreateDXGIDeviceManager);
663 X(MFCreateSourceResolver);
664 X(MFCreateMFByteStreamOnStream);
665 X(MFCreateTransformActivate);
666 X(MFGetPlaneSize);
667 X(MFHeapAlloc);
668 X(MFHeapFree);
669 X(MFPutWaitingWorkItem);
670 X(MFRegisterLocalByteStreamHandler);
671 X(MFRegisterLocalSchemeHandler);
672 X(MFRemovePeriodicCallback);
673 X(MFTEnumEx);
674 X(MFTRegisterLocal);
675 X(MFTRegisterLocalByCLSID);
676 X(MFTUnregisterLocal);
677 X(MFTUnregisterLocalByCLSID);
679 if ((mod = LoadLibraryA("d3d11.dll")))
681 X(D3D11CreateDevice);
684 mod = GetModuleHandleA("ole32.dll");
686 X(CoGetApartmentType);
687 #undef X
689 is_win8_plus = pMFPutWaitingWorkItem != NULL;
692 static void test_media_type(void)
694 IMFMediaType *mediatype, *mediatype2;
695 BOOL compressed;
696 DWORD flags;
697 HRESULT hr;
698 GUID guid;
700 if(0)
702 /* Crash on Windows Vista/7 */
703 hr = MFCreateMediaType(NULL);
704 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
707 hr = MFCreateMediaType(&mediatype);
708 ok(hr == S_OK, "got 0x%08x\n", hr);
710 hr = IMFMediaType_GetMajorType(mediatype, &guid);
711 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
713 compressed = FALSE;
714 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
715 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
716 ok(compressed, "Unexpected value %d.\n", compressed);
718 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
719 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
721 compressed = FALSE;
722 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
723 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
724 ok(compressed, "Unexpected value %d.\n", compressed);
726 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
727 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
729 compressed = TRUE;
730 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
731 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
732 ok(!compressed, "Unexpected value %d.\n", compressed);
734 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
735 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
737 hr = IMFMediaType_GetMajorType(mediatype, &guid);
738 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
739 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
741 /* IsEqual() */
742 hr = MFCreateMediaType(&mediatype2);
743 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
745 flags = 0xdeadbeef;
746 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
747 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
748 ok(flags == 0, "Unexpected flags %#x.\n", flags);
750 /* Different major types. */
751 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
752 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
754 flags = 0;
755 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
756 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
757 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
758 "Unexpected flags %#x.\n", flags);
760 /* Same major types, different subtypes. */
761 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
762 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
764 flags = 0;
765 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
766 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
767 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
768 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
770 /* Different user data. */
771 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
772 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
774 flags = 0;
775 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
776 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
777 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
778 "Unexpected flags %#x.\n", flags);
780 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
781 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
783 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
784 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
786 flags = 0;
787 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
788 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
789 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
790 "Unexpected flags %#x.\n", flags);
792 IMFMediaType_Release(mediatype2);
793 IMFMediaType_Release(mediatype);
796 static void test_MFCreateMediaEvent(void)
798 HRESULT hr;
799 IMFMediaEvent *mediaevent;
801 MediaEventType type;
802 GUID extended_type;
803 HRESULT status;
804 PROPVARIANT value;
806 PropVariantInit(&value);
807 value.vt = VT_UNKNOWN;
809 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
810 ok(hr == S_OK, "got 0x%08x\n", hr);
812 PropVariantClear(&value);
814 hr = IMFMediaEvent_GetType(mediaevent, &type);
815 ok(hr == S_OK, "got 0x%08x\n", hr);
816 ok(type == MEError, "got %#x\n", type);
818 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
819 ok(hr == S_OK, "got 0x%08x\n", hr);
820 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
821 wine_dbgstr_guid(&extended_type));
823 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
824 ok(hr == S_OK, "got 0x%08x\n", hr);
825 ok(status == E_FAIL, "got 0x%08x\n", status);
827 PropVariantInit(&value);
828 hr = IMFMediaEvent_GetValue(mediaevent, &value);
829 ok(hr == S_OK, "got 0x%08x\n", hr);
830 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
831 PropVariantClear(&value);
833 IMFMediaEvent_Release(mediaevent);
835 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
836 ok(hr == S_OK, "got 0x%08x\n", hr);
838 hr = IMFMediaEvent_GetType(mediaevent, &type);
839 ok(hr == S_OK, "got 0x%08x\n", hr);
840 ok(type == MEUnknown, "got %#x\n", type);
842 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
843 ok(hr == S_OK, "got 0x%08x\n", hr);
844 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
845 wine_dbgstr_guid(&extended_type));
847 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
848 ok(hr == S_OK, "got 0x%08x\n", hr);
849 ok(status == S_OK, "got 0x%08x\n", status);
851 PropVariantInit(&value);
852 hr = IMFMediaEvent_GetValue(mediaevent, &value);
853 ok(hr == S_OK, "got 0x%08x\n", hr);
854 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
855 PropVariantClear(&value);
857 IMFMediaEvent_Release(mediaevent);
860 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
861 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
863 UINT32 count = expected + 1;
864 HRESULT hr = IMFAttributes_GetCount(obj, &count);
865 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
866 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
869 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
870 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
872 MF_ATTRIBUTE_TYPE type;
873 HRESULT hr;
875 hr = IMFAttributes_GetItemType(obj, key, &type);
876 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
877 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
880 static void test_attributes(void)
882 static const WCHAR stringW[] = L"Wine";
883 static const UINT8 blob[] = {0,1,2,3,4,5};
884 IMFAttributes *attributes, *attributes1;
885 UINT8 blob_value[256], *blob_buf = NULL;
886 MF_ATTRIBUTES_MATCH_TYPE match_type;
887 UINT32 value, string_length, size;
888 PROPVARIANT propvar, ret_propvar;
889 MF_ATTRIBUTE_TYPE type;
890 double double_value;
891 IUnknown *unk_value;
892 WCHAR bufferW[256];
893 UINT64 value64;
894 WCHAR *string;
895 BOOL result;
896 HRESULT hr;
897 GUID key;
899 hr = MFCreateAttributes( &attributes, 3 );
900 ok(hr == S_OK, "got 0x%08x\n", hr);
902 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
903 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
905 CHECK_ATTR_COUNT(attributes, 0);
906 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
907 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
908 CHECK_ATTR_COUNT(attributes, 1);
909 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
911 value = 0xdeadbeef;
912 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
913 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
914 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
916 value64 = 0xdeadbeef;
917 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
918 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
919 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
921 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
922 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
923 CHECK_ATTR_COUNT(attributes, 1);
924 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
926 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
927 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
928 ok(value64 == 65536, "Unexpected value.\n");
930 value = 0xdeadbeef;
931 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
932 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
933 ok(value == 0xdeadbeef, "Unexpected value.\n");
935 IMFAttributes_Release(attributes);
937 hr = MFCreateAttributes(&attributes, 0);
938 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
940 PropVariantInit(&propvar);
941 propvar.vt = MF_ATTRIBUTE_UINT32;
942 U(propvar).ulVal = 123;
943 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
944 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
945 PropVariantInit(&ret_propvar);
946 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
947 U(ret_propvar).ulVal = 0xdeadbeef;
948 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
949 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
950 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
951 PropVariantClear(&ret_propvar);
952 CHECK_ATTR_COUNT(attributes, 1);
954 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
955 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
957 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
958 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
960 PropVariantInit(&ret_propvar);
961 ret_propvar.vt = MF_ATTRIBUTE_STRING;
962 U(ret_propvar).pwszVal = NULL;
963 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
964 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
965 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
966 PropVariantClear(&ret_propvar);
968 PropVariantClear(&propvar);
970 PropVariantInit(&propvar);
971 propvar.vt = MF_ATTRIBUTE_UINT64;
972 U(propvar).uhVal.QuadPart = 65536;
973 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
974 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
975 PropVariantInit(&ret_propvar);
976 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
977 U(ret_propvar).ulVal = 0xdeadbeef;
978 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
979 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
980 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
981 PropVariantClear(&ret_propvar);
982 PropVariantClear(&propvar);
983 CHECK_ATTR_COUNT(attributes, 1);
985 PropVariantInit(&propvar);
986 propvar.vt = VT_I4;
987 U(propvar).lVal = 123;
988 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
989 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
990 PropVariantInit(&ret_propvar);
991 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
992 U(ret_propvar).lVal = 0xdeadbeef;
993 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
994 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
995 PropVariantClear(&propvar);
996 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
997 PropVariantClear(&ret_propvar);
999 PropVariantInit(&propvar);
1000 propvar.vt = MF_ATTRIBUTE_UINT32;
1001 U(propvar).ulVal = 123;
1002 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1003 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1005 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1006 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1007 CHECK_ATTR_COUNT(attributes, 2);
1009 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1010 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1011 CHECK_ATTR_COUNT(attributes, 2);
1013 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1014 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1015 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1016 PropVariantClear(&ret_propvar);
1017 PropVariantClear(&propvar);
1019 propvar.vt = MF_ATTRIBUTE_UINT64;
1020 U(propvar).uhVal.QuadPart = 65536;
1022 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1023 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1024 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1025 PropVariantClear(&ret_propvar);
1026 PropVariantClear(&propvar);
1028 /* Item ordering is not consistent across Windows version. */
1029 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1030 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1031 PropVariantClear(&ret_propvar);
1033 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1034 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1035 PropVariantClear(&ret_propvar);
1037 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1038 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
1039 CHECK_ATTR_COUNT(attributes, 3);
1040 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1042 double_value = 0xdeadbeef;
1043 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1044 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
1045 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1047 propvar.vt = MF_ATTRIBUTE_UINT64;
1048 U(propvar).uhVal.QuadPart = 22;
1049 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1050 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1051 ok(!result, "Unexpected result.\n");
1053 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1054 U(propvar).dblVal = 22.0;
1055 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1056 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1057 ok(result, "Unexpected result.\n");
1059 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1060 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
1061 CHECK_ATTR_COUNT(attributes, 3);
1062 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1064 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1065 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
1066 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1068 string_length = 0xdeadbeef;
1069 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1070 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
1071 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1072 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1073 CoTaskMemFree(string);
1075 string_length = 0xdeadbeef;
1076 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1077 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1078 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1079 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1080 memset(bufferW, 0, sizeof(bufferW));
1082 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1083 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1084 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1085 memset(bufferW, 0, sizeof(bufferW));
1087 string_length = 0;
1088 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1089 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1090 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1091 ok(string_length, "Unexpected length.\n");
1093 string_length = 0xdeadbeef;
1094 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1095 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1096 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1098 /* VT_UNKNOWN */
1099 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1100 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1101 CHECK_ATTR_COUNT(attributes, 4);
1102 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1104 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1105 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1106 IUnknown_Release(unk_value);
1108 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1109 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1110 IUnknown_Release(unk_value);
1112 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1113 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1115 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1116 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1117 CHECK_ATTR_COUNT(attributes, 5);
1119 unk_value = NULL;
1120 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1121 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1123 /* CopyAllItems() */
1124 hr = MFCreateAttributes(&attributes1, 0);
1125 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1126 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1127 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1128 CHECK_ATTR_COUNT(attributes, 5);
1129 CHECK_ATTR_COUNT(attributes1, 5);
1131 hr = IMFAttributes_DeleteAllItems(attributes1);
1132 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
1133 CHECK_ATTR_COUNT(attributes1, 0);
1135 propvar.vt = MF_ATTRIBUTE_UINT64;
1136 U(propvar).uhVal.QuadPart = 22;
1137 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1138 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1139 ok(!result, "Unexpected result.\n");
1141 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1142 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1143 CHECK_ATTR_COUNT(attributes, 0);
1145 /* Blob */
1146 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1147 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
1148 CHECK_ATTR_COUNT(attributes, 1);
1149 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1150 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1151 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1152 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1154 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1155 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1157 size = 0;
1158 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1159 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1160 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1161 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1163 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1164 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1166 memset(blob_value, 0, sizeof(blob_value));
1167 size = 0;
1168 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1169 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1170 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1171 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1172 CoTaskMemFree(blob_buf);
1174 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1175 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1177 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1178 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1180 IMFAttributes_Release(attributes);
1181 IMFAttributes_Release(attributes1);
1183 /* Compare() */
1184 hr = MFCreateAttributes(&attributes, 0);
1185 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1186 hr = MFCreateAttributes(&attributes1, 0);
1187 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1189 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1190 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1192 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1194 result = FALSE;
1195 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1196 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1197 ok(result, "Unexpected result %d.\n", result);
1199 result = FALSE;
1200 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1201 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1202 ok(result, "Unexpected result %d.\n", result);
1205 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1206 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1208 result = TRUE;
1209 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1210 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1211 ok(!result, "Unexpected result %d.\n", result);
1213 result = TRUE;
1214 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1215 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1216 ok(!result, "Unexpected result %d.\n", result);
1218 result = FALSE;
1219 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1220 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1221 ok(result, "Unexpected result %d.\n", result);
1223 result = FALSE;
1224 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1225 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1226 ok(result, "Unexpected result %d.\n", result);
1228 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1229 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1231 result = TRUE;
1232 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1233 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1234 ok(!result, "Unexpected result %d.\n", result);
1236 result = TRUE;
1237 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1238 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1239 ok(!result, "Unexpected result %d.\n", result);
1241 result = TRUE;
1242 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1243 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1244 ok(!result, "Unexpected result %d.\n", result);
1246 result = TRUE;
1247 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1248 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1249 ok(!result, "Unexpected result %d.\n", result);
1251 result = TRUE;
1252 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1253 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1254 ok(!result, "Unexpected result %d.\n", result);
1256 result = TRUE;
1257 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1258 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1259 ok(!result, "Unexpected result %d.\n", result);
1261 result = TRUE;
1262 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1263 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1264 ok(!result, "Unexpected result %d.\n", result);
1266 result = TRUE;
1267 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1268 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1269 ok(!result, "Unexpected result %d.\n", result);
1271 result = TRUE;
1272 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1273 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1274 ok(!result, "Unexpected result %d.\n", result);
1276 result = TRUE;
1277 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1278 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1279 ok(!result, "Unexpected result %d.\n", result);
1281 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1282 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1284 result = FALSE;
1285 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1286 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1287 ok(result, "Unexpected result %d.\n", result);
1289 result = FALSE;
1290 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1291 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1292 ok(result, "Unexpected result %d.\n", result);
1294 result = FALSE;
1295 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1296 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1297 ok(result, "Unexpected result %d.\n", result);
1299 result = FALSE;
1300 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1301 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1302 ok(result, "Unexpected result %d.\n", result);
1304 result = FALSE;
1305 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1306 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1307 ok(result, "Unexpected result %d.\n", result);
1309 result = FALSE;
1310 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1311 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1312 ok(result, "Unexpected result %d.\n", result);
1314 result = FALSE;
1315 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1316 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1317 ok(result, "Unexpected result %d.\n", result);
1319 result = FALSE;
1320 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1321 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1322 ok(result, "Unexpected result %d.\n", result);
1324 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1325 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1327 result = TRUE;
1328 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1329 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1330 ok(!result, "Unexpected result %d.\n", result);
1332 result = TRUE;
1333 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1334 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1335 ok(!result, "Unexpected result %d.\n", result);
1337 result = FALSE;
1338 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1339 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1340 ok(result, "Unexpected result %d.\n", result);
1342 result = FALSE;
1343 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1344 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1345 ok(result, "Unexpected result %d.\n", result);
1347 result = FALSE;
1348 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1349 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1350 ok(result, "Unexpected result %d.\n", result);
1352 result = TRUE;
1353 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1354 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1355 ok(!result, "Unexpected result %d.\n", result);
1357 result = FALSE;
1358 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1359 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1360 ok(result, "Unexpected result %d.\n", result);
1362 result = TRUE;
1363 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1364 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1365 ok(!result, "Unexpected result %d.\n", result);
1367 result = FALSE;
1368 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1369 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1370 ok(result, "Unexpected result %d.\n", result);
1372 result = FALSE;
1373 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1374 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1375 ok(result, "Unexpected result %d.\n", result);
1377 IMFAttributes_Release(attributes);
1378 IMFAttributes_Release(attributes1);
1381 static void test_MFCreateMFByteStreamOnStream(void)
1383 IMFByteStream *bytestream;
1384 IMFByteStream *bytestream2;
1385 IStream *stream;
1386 IMFAttributes *attributes = NULL;
1387 DWORD caps, written, count;
1388 IUnknown *unknown;
1389 ULONG ref, size;
1390 HRESULT hr;
1392 if(!pMFCreateMFByteStreamOnStream)
1394 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1395 return;
1398 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1399 ok(hr == S_OK, "got 0x%08x\n", hr);
1401 caps = 0xffff0000;
1402 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1403 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1405 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1406 ok(hr == S_OK, "got 0x%08x\n", hr);
1408 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1409 (void **)&unknown);
1410 ok(hr == S_OK, "got 0x%08x\n", hr);
1411 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1412 ref = IUnknown_Release(unknown);
1413 ok(ref == 1, "got %u\n", ref);
1415 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1416 (void **)&bytestream2);
1417 ok(hr == S_OK, "got 0x%08x\n", hr);
1418 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1419 ref = IMFByteStream_Release(bytestream2);
1420 ok(ref == 1, "got %u\n", ref);
1422 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1423 (void **)&attributes);
1424 ok(hr == S_OK ||
1425 /* w7pro64 */
1426 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1428 if (hr != S_OK)
1430 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1431 IStream_Release(stream);
1432 IMFByteStream_Release(bytestream);
1433 return;
1436 ok(attributes != NULL, "got NULL\n");
1437 hr = IMFAttributes_GetCount(attributes, &count);
1438 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1439 ok(count == 0, "Unexpected attributes count %u.\n", count);
1441 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1442 (void **)&unknown);
1443 ok(hr == S_OK, "got 0x%08x\n", hr);
1444 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1445 ref = IUnknown_Release(unknown);
1446 ok(ref == 2, "got %u\n", ref);
1448 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1449 (void **)&bytestream2);
1450 ok(hr == S_OK, "got 0x%08x\n", hr);
1451 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1452 ref = IMFByteStream_Release(bytestream2);
1453 ok(ref == 2, "got %u\n", ref);
1455 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamBuffering, (void **)&unknown);
1456 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1458 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamCacheControl, (void **)&unknown);
1459 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1461 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFMediaEventGenerator, (void **)&unknown);
1462 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1464 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFGetService, (void **)&unknown);
1465 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1467 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1468 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1469 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1471 hr = IMFByteStream_Close(bytestream);
1472 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1474 hr = IMFByteStream_Close(bytestream);
1475 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1477 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1478 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1479 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1481 caps = 0;
1482 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1483 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1484 ok(caps == 0xffff0000, "Unexpected content.\n");
1486 IMFAttributes_Release(attributes);
1487 IMFByteStream_Release(bytestream);
1488 IStream_Release(stream);
1491 static void test_file_stream(void)
1493 static const WCHAR newfilename[] = L"new.mp4";
1494 IMFByteStream *bytestream, *bytestream2;
1495 QWORD bytestream_length, position;
1496 IMFAttributes *attributes = NULL;
1497 MF_ATTRIBUTE_TYPE item_type;
1498 WCHAR pathW[MAX_PATH];
1499 DWORD caps, count;
1500 WCHAR *filename;
1501 IUnknown *unk;
1502 HRESULT hr;
1503 WCHAR *str;
1504 BOOL eos;
1506 filename = load_resource(L"test.mp4");
1508 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1509 ok(hr == S_OK, "got 0x%08x\n", hr);
1511 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1512 MF_FILEFLAGS_NONE, filename, &bytestream);
1513 ok(hr == S_OK, "got 0x%08x\n", hr);
1515 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamBuffering, (void **)&unk);
1516 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1518 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamCacheControl, (void **)&unk);
1519 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1521 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFMediaEventGenerator, (void **)&unk);
1522 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1524 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFGetService, (void **)&unk);
1525 ok(hr == S_OK, "Failed to get interface pointer, hr %#x.\n", hr);
1526 IUnknown_Release(unk);
1528 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1529 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1530 if (is_win8_plus)
1532 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1533 "Unexpected caps %#x.\n", caps);
1535 else
1536 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1538 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1539 (void **)&attributes);
1540 ok(hr == S_OK, "got 0x%08x\n", hr);
1541 ok(attributes != NULL, "got NULL\n");
1543 hr = IMFAttributes_GetCount(attributes, &count);
1544 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1545 ok(count == 2, "Unexpected attributes count %u.\n", count);
1547 /* Original file name. */
1548 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1549 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1550 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1551 CoTaskMemFree(str);
1553 /* Modification time. */
1554 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1555 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1556 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1558 IMFAttributes_Release(attributes);
1560 /* Length. */
1561 hr = IMFByteStream_GetLength(bytestream, NULL);
1562 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1564 bytestream_length = 0;
1565 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1566 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1567 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1569 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1570 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1572 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1573 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1574 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1576 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1577 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1579 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1580 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1582 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1583 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1584 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1586 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1587 MF_FILEFLAGS_NONE, filename, &bytestream2);
1588 ok(hr == S_OK, "got 0x%08x\n", hr);
1589 IMFByteStream_Release(bytestream2);
1591 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1592 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1594 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1595 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1597 IMFByteStream_Release(bytestream);
1599 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1600 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1601 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1603 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1604 MF_FILEFLAGS_NONE, filename, &bytestream);
1605 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1607 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1608 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1609 ok(hr == S_OK, "got 0x%08x\n", hr);
1611 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1612 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1614 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1615 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1617 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1618 newfilename, &bytestream2);
1619 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1621 IMFByteStream_Release(bytestream);
1623 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1624 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1625 ok(hr == S_OK, "got 0x%08x\n", hr);
1627 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1628 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1629 newfilename, &bytestream2);
1630 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1632 IMFByteStream_Release(bytestream);
1634 /* Explicit file: scheme */
1635 lstrcpyW(pathW, fileschemeW);
1636 lstrcatW(pathW, filename);
1637 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
1638 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1640 hr = MFShutdown();
1641 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1643 DeleteFileW(filename);
1644 DeleteFileW(newfilename);
1647 static void test_system_memory_buffer(void)
1649 IMFMediaBuffer *buffer;
1650 HRESULT hr;
1651 DWORD length, max;
1652 BYTE *data, *data2;
1654 hr = MFCreateMemoryBuffer(1024, NULL);
1655 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1657 hr = MFCreateMemoryBuffer(0, &buffer);
1658 ok(hr == S_OK, "got 0x%08x\n", hr);
1659 if(buffer)
1661 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1662 ok(hr == S_OK, "got 0x%08x\n", hr);
1663 ok(length == 0, "got %u\n", length);
1665 IMFMediaBuffer_Release(buffer);
1668 hr = MFCreateMemoryBuffer(1024, &buffer);
1669 ok(hr == S_OK, "got 0x%08x\n", hr);
1671 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
1672 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1674 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1675 ok(hr == S_OK, "got 0x%08x\n", hr);
1676 ok(length == 1024, "got %u\n", length);
1678 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
1679 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1681 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1682 ok(hr == S_OK, "got 0x%08x\n", hr);
1684 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
1685 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1687 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1688 ok(hr == S_OK, "got 0x%08x\n", hr);
1689 ok(length == 10, "got %u\n", length);
1691 length = 0;
1692 max = 0;
1693 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
1694 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1695 ok(length == 0, "got %u\n", length);
1696 ok(max == 0, "got %u\n", length);
1698 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1699 ok(hr == S_OK, "got 0x%08x\n", hr);
1700 ok(length == 10, "got %u\n", length);
1701 ok(max == 1024, "got %u\n", max);
1703 /* Attempt to lock the buffer twice */
1704 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
1705 ok(hr == S_OK, "got 0x%08x\n", hr);
1706 ok(data == data2, "got 0x%08x\n", hr);
1708 hr = IMFMediaBuffer_Unlock(buffer);
1709 ok(hr == S_OK, "got 0x%08x\n", hr);
1711 hr = IMFMediaBuffer_Unlock(buffer);
1712 ok(hr == S_OK, "got 0x%08x\n", hr);
1714 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1715 ok(hr == S_OK, "got 0x%08x\n", hr);
1717 hr = IMFMediaBuffer_Unlock(buffer);
1718 ok(hr == S_OK, "got 0x%08x\n", hr);
1720 /* Extra Unlock */
1721 hr = IMFMediaBuffer_Unlock(buffer);
1722 ok(hr == S_OK, "got 0x%08x\n", hr);
1724 IMFMediaBuffer_Release(buffer);
1726 /* Aligned buffer. */
1727 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
1728 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
1730 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1731 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1732 ok(length == 0, "Unexpected current length %u.\n", length);
1734 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
1735 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1736 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1737 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1738 ok(length == 1, "Unexpected current length %u.\n", length);
1740 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1741 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1742 ok(length == 201, "Unexpected max length %u.\n", length);
1744 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
1745 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1746 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1747 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1748 ok(length == 201, "Unexpected max length %u.\n", length);
1749 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1750 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1752 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1753 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
1754 ok(max == 201 && length == 10, "Unexpected length.\n");
1755 hr = IMFMediaBuffer_Unlock(buffer);
1756 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
1758 IMFMediaBuffer_Release(buffer);
1761 static void test_sample(void)
1763 static const DWORD test_pattern = 0x22222222;
1764 IMFMediaBuffer *buffer, *buffer2;
1765 DWORD count, flags, length;
1766 IMFAttributes *attributes;
1767 IMFSample *sample;
1768 LONGLONG time;
1769 HRESULT hr;
1770 BYTE *data;
1772 hr = MFCreateSample( &sample );
1773 ok(hr == S_OK, "got 0x%08x\n", hr);
1775 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
1776 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
1778 CHECK_ATTR_COUNT(attributes, 0);
1780 hr = IMFSample_GetBufferCount(sample, NULL);
1781 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1783 hr = IMFSample_GetBufferCount(sample, &count);
1784 ok(hr == S_OK, "got 0x%08x\n", hr);
1785 ok(count == 0, "got %d\n", count);
1787 hr = IMFSample_GetSampleFlags(sample, &flags);
1788 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
1789 ok(!flags, "Unexpected flags %#x.\n", flags);
1791 hr = IMFSample_SetSampleFlags(sample, 0x123);
1792 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
1793 hr = IMFSample_GetSampleFlags(sample, &flags);
1794 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
1795 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
1797 hr = IMFSample_GetSampleTime(sample, &time);
1798 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
1800 hr = IMFSample_GetSampleDuration(sample, &time);
1801 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
1803 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1804 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1806 hr = IMFSample_RemoveBufferByIndex(sample, 0);
1807 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1809 hr = IMFSample_RemoveAllBuffers(sample);
1810 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
1812 hr = IMFSample_GetTotalLength(sample, &length);
1813 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1814 ok(!length, "Unexpected total length %u.\n", length);
1816 hr = MFCreateMemoryBuffer(16, &buffer);
1817 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
1819 hr = IMFSample_AddBuffer(sample, buffer);
1820 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1822 hr = IMFSample_AddBuffer(sample, buffer);
1823 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1825 hr = IMFSample_GetBufferCount(sample, &count);
1826 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1827 ok(count == 2, "Unexpected buffer count %u.\n", count);
1829 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
1830 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
1831 ok(buffer2 == buffer, "Unexpected object.\n");
1832 IMFMediaBuffer_Release(buffer2);
1834 hr = IMFSample_GetTotalLength(sample, &length);
1835 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1836 ok(!length, "Unexpected total length %u.\n", length);
1838 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
1839 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1841 hr = IMFSample_GetTotalLength(sample, &length);
1842 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1843 ok(length == 4, "Unexpected total length %u.\n", length);
1845 hr = IMFSample_RemoveBufferByIndex(sample, 1);
1846 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
1848 hr = IMFSample_GetTotalLength(sample, &length);
1849 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1850 ok(length == 2, "Unexpected total length %u.\n", length);
1852 IMFMediaBuffer_Release(buffer);
1854 /* Duration */
1855 hr = IMFSample_SetSampleDuration(sample, 10);
1856 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
1857 CHECK_ATTR_COUNT(attributes, 0);
1858 hr = IMFSample_GetSampleDuration(sample, &time);
1859 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
1860 ok(time == 10, "Unexpected duration.\n");
1862 /* Timestamp */
1863 hr = IMFSample_SetSampleTime(sample, 1);
1864 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
1865 CHECK_ATTR_COUNT(attributes, 0);
1866 hr = IMFSample_GetSampleTime(sample, &time);
1867 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
1868 ok(time == 1, "Unexpected timestamp.\n");
1870 IMFAttributes_Release(attributes);
1871 IMFSample_Release(sample);
1873 /* CopyToBuffer() */
1874 hr = MFCreateSample(&sample);
1875 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
1877 hr = MFCreateMemoryBuffer(16, &buffer2);
1878 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1880 /* Sample with no buffers. */
1881 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
1882 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1883 hr = IMFSample_CopyToBuffer(sample, buffer2);
1884 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1885 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
1886 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1887 ok(!length, "Unexpected length %u.\n", length);
1889 /* Single buffer, larger destination. */
1890 hr = MFCreateMemoryBuffer(8, &buffer);
1891 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1893 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1894 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
1895 *(DWORD *)data = 0x11111111;
1896 hr = IMFMediaBuffer_Unlock(buffer);
1897 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
1898 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
1899 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1901 hr = IMFSample_AddBuffer(sample, buffer);
1902 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1904 /* Existing content is overwritten. */
1905 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
1906 ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
1908 hr = IMFSample_CopyToBuffer(sample, buffer2);
1909 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
1911 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
1912 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
1913 ok(length == 4, "Unexpected buffer length %u.\n", length);
1915 /* Multiple buffers, matching total size. */
1916 hr = IMFSample_AddBuffer(sample, buffer);
1917 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1919 hr = IMFSample_GetBufferCount(sample, &count);
1920 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1921 ok(count == 2, "Unexpected buffer count %u.\n", count);
1923 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
1924 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1926 hr = IMFSample_CopyToBuffer(sample, buffer2);
1927 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
1929 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
1930 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
1931 ok(length == 16, "Unexpected buffer length %u.\n", length);
1933 hr = IMFSample_AddBuffer(sample, buffer);
1934 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1936 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
1937 ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
1939 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
1940 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
1941 *(DWORD *)data = test_pattern;
1942 hr = IMFMediaBuffer_Unlock(buffer2);
1943 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
1945 hr = IMFSample_CopyToBuffer(sample, buffer2);
1946 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
1948 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
1949 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
1950 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
1951 hr = IMFMediaBuffer_Unlock(buffer2);
1952 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
1954 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
1955 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
1956 ok(!length, "Unexpected buffer length %u.\n", length);
1958 IMFMediaBuffer_Release(buffer2);
1959 IMFSample_Release(sample);
1961 /* ConvertToContiguousBuffer() */
1962 hr = MFCreateSample(&sample);
1963 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
1965 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
1966 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
1968 hr = MFCreateMemoryBuffer(16, &buffer);
1969 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1971 hr = IMFSample_AddBuffer(sample, buffer);
1972 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1974 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1975 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1976 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
1977 IMFMediaBuffer_Release(buffer2);
1979 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1980 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1981 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
1982 IMFMediaBuffer_Release(buffer2);
1984 hr = MFCreateMemoryBuffer(16, &buffer2);
1985 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1987 hr = IMFSample_AddBuffer(sample, buffer2);
1988 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1989 IMFMediaBuffer_Release(buffer2);
1991 hr = IMFSample_GetBufferCount(sample, &count);
1992 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1993 ok(count == 2, "Unexpected buffer count %u.\n", count);
1995 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1996 todo_wine
1997 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1998 if (SUCCEEDED(hr))
1999 IMFMediaBuffer_Release(buffer2);
2001 hr = IMFSample_GetBufferCount(sample, &count);
2002 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2003 todo_wine
2004 ok(count == 1, "Unexpected buffer count %u.\n", count);
2006 IMFMediaBuffer_Release(buffer);
2008 IMFSample_Release(sample);
2011 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2013 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2014 IMFMediaEventQueue *queue;
2015 IUnknown *state, *obj;
2016 HRESULT hr;
2018 ok(result != NULL, "Unexpected result object.\n");
2020 state = IMFAsyncResult_GetStateNoAddRef(result);
2021 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2023 IMFMediaEvent *event;
2025 if (is_win8_plus)
2027 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2028 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2030 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2031 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2033 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2034 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
2036 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2037 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
2039 IMFMediaEvent_Release(event);
2042 hr = IMFAsyncResult_GetObject(result, &obj);
2043 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2045 IMFMediaEventQueue_Release(queue);
2047 SetEvent(callback->event);
2050 return E_NOTIMPL;
2053 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2055 testcallback_QueryInterface,
2056 testcallback_AddRef,
2057 testcallback_Release,
2058 testcallback_GetParameters,
2059 testcallback_Invoke,
2062 static void init_test_callback(struct test_callback *callback)
2064 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
2065 callback->event = NULL;
2068 static void test_MFCreateAsyncResult(void)
2070 IMFAsyncResult *result, *result2;
2071 struct test_callback callback;
2072 IUnknown *state, *object;
2073 MFASYNCRESULT *data;
2074 ULONG refcount;
2075 HANDLE event;
2076 DWORD flags;
2077 HRESULT hr;
2078 BOOL ret;
2080 init_test_callback(&callback);
2082 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2083 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2085 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2086 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2088 data = (MFASYNCRESULT *)result;
2089 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2090 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2091 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2092 ok(data->hEvent == NULL, "Unexpected event.\n");
2094 hr = IMFAsyncResult_GetState(result, NULL);
2095 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2097 state = (void *)0xdeadbeef;
2098 hr = IMFAsyncResult_GetState(result, &state);
2099 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2100 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2102 hr = IMFAsyncResult_GetStatus(result);
2103 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
2105 data->hrStatusResult = 123;
2106 hr = IMFAsyncResult_GetStatus(result);
2107 ok(hr == 123, "Unexpected status %#x.\n", hr);
2109 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2110 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
2111 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
2113 hr = IMFAsyncResult_GetObject(result, NULL);
2114 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2116 object = (void *)0xdeadbeef;
2117 hr = IMFAsyncResult_GetObject(result, &object);
2118 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
2119 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2121 state = IMFAsyncResult_GetStateNoAddRef(result);
2122 ok(state == NULL, "Unexpected state.\n");
2124 /* Object. */
2125 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
2126 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2128 data = (MFASYNCRESULT *)result2;
2129 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2130 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2131 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2132 ok(data->hEvent == NULL, "Unexpected event.\n");
2134 object = NULL;
2135 hr = IMFAsyncResult_GetObject(result2, &object);
2136 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
2137 ok(object == (IUnknown *)result, "Unexpected object.\n");
2138 IUnknown_Release(object);
2140 IMFAsyncResult_Release(result2);
2142 /* State object. */
2143 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2144 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2146 data = (MFASYNCRESULT *)result2;
2147 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2148 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2149 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2150 ok(data->hEvent == NULL, "Unexpected event.\n");
2152 state = NULL;
2153 hr = IMFAsyncResult_GetState(result2, &state);
2154 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
2155 ok(state == (IUnknown *)result, "Unexpected state.\n");
2156 IUnknown_Release(state);
2158 state = IMFAsyncResult_GetStateNoAddRef(result2);
2159 ok(state == (IUnknown *)result, "Unexpected state.\n");
2161 refcount = IMFAsyncResult_Release(result2);
2162 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2163 refcount = IMFAsyncResult_Release(result);
2164 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2166 /* Event handle is closed on release. */
2167 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2168 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2170 data = (MFASYNCRESULT *)result;
2171 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2172 ok(data->hEvent != NULL, "Failed to create event.\n");
2173 ret = GetHandleInformation(event, &flags);
2174 ok(ret, "Failed to get handle info.\n");
2176 refcount = IMFAsyncResult_Release(result);
2177 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2178 ret = GetHandleInformation(event, &flags);
2179 ok(!ret, "Expected handle to be closed.\n");
2181 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2182 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2184 data = (MFASYNCRESULT *)result;
2185 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2186 ok(data->hEvent != NULL, "Failed to create event.\n");
2187 ret = GetHandleInformation(event, &flags);
2188 ok(ret, "Failed to get handle info.\n");
2190 refcount = IMFAsyncResult_Release(result);
2191 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2192 ret = GetHandleInformation(event, &flags);
2193 ok(!ret, "Expected handle to be closed.\n");
2196 static void test_startup(void)
2198 DWORD queue;
2199 HRESULT hr;
2201 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2202 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
2204 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2205 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2207 hr = MFAllocateWorkQueue(&queue);
2208 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2209 hr = MFUnlockWorkQueue(queue);
2210 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2212 hr = MFShutdown();
2213 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2215 hr = MFAllocateWorkQueue(&queue);
2216 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2218 /* Already shut down, has no effect. */
2219 hr = MFShutdown();
2220 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2222 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2223 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2225 hr = MFAllocateWorkQueue(&queue);
2226 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2227 hr = MFUnlockWorkQueue(queue);
2228 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2230 hr = MFShutdown();
2231 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2233 /* Platform lock. */
2234 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2235 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2237 hr = MFAllocateWorkQueue(&queue);
2238 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2239 hr = MFUnlockWorkQueue(queue);
2240 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2242 /* Unlocking implies shutdown. */
2243 hr = MFUnlockPlatform();
2244 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2246 hr = MFAllocateWorkQueue(&queue);
2247 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2249 hr = MFLockPlatform();
2250 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2252 hr = MFAllocateWorkQueue(&queue);
2253 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2254 hr = MFUnlockWorkQueue(queue);
2255 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2257 hr = MFShutdown();
2258 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2261 static void test_allocate_queue(void)
2263 DWORD queue, queue2;
2264 HRESULT hr;
2266 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2267 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2269 hr = MFAllocateWorkQueue(&queue);
2270 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2271 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2273 hr = MFUnlockWorkQueue(queue);
2274 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2276 hr = MFUnlockWorkQueue(queue);
2277 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2279 hr = MFAllocateWorkQueue(&queue2);
2280 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2281 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2283 hr = MFUnlockWorkQueue(queue2);
2284 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2286 /* Unlock in system queue range. */
2287 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2288 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2290 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2291 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2293 hr = MFUnlockWorkQueue(0x20);
2294 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2296 hr = MFShutdown();
2297 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2300 static void test_MFCopyImage(void)
2302 BYTE dest[16], src[16];
2303 HRESULT hr;
2305 if (!pMFCopyImage)
2307 win_skip("MFCopyImage() is not available.\n");
2308 return;
2311 memset(dest, 0xaa, sizeof(dest));
2312 memset(src, 0x11, sizeof(src));
2314 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2315 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2316 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2318 memset(dest, 0xaa, sizeof(dest));
2319 memset(src, 0x11, sizeof(src));
2321 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2322 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2323 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2325 memset(dest, 0xaa, sizeof(dest));
2326 memset(src, 0x11, sizeof(src));
2328 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2329 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2330 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2333 static void test_MFCreateCollection(void)
2335 IMFCollection *collection;
2336 IUnknown *element;
2337 DWORD count;
2338 HRESULT hr;
2340 hr = MFCreateCollection(NULL);
2341 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2343 hr = MFCreateCollection(&collection);
2344 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2346 hr = IMFCollection_GetElementCount(collection, NULL);
2347 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2349 count = 1;
2350 hr = IMFCollection_GetElementCount(collection, &count);
2351 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2352 ok(count == 0, "Unexpected count %u.\n", count);
2354 hr = IMFCollection_GetElement(collection, 0, NULL);
2355 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2357 element = (void *)0xdeadbeef;
2358 hr = IMFCollection_GetElement(collection, 0, &element);
2359 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2360 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2362 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2363 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2365 element = (void *)0xdeadbeef;
2366 hr = IMFCollection_RemoveElement(collection, 0, &element);
2367 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2368 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2370 hr = IMFCollection_RemoveAllElements(collection);
2371 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2373 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2374 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2376 count = 0;
2377 hr = IMFCollection_GetElementCount(collection, &count);
2378 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2379 ok(count == 1, "Unexpected count %u.\n", count);
2381 hr = IMFCollection_AddElement(collection, NULL);
2382 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2384 count = 0;
2385 hr = IMFCollection_GetElementCount(collection, &count);
2386 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2387 ok(count == 2, "Unexpected count %u.\n", count);
2389 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2390 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2392 count = 0;
2393 hr = IMFCollection_GetElementCount(collection, &count);
2394 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2395 ok(count == 11, "Unexpected count %u.\n", count);
2397 hr = IMFCollection_GetElement(collection, 0, &element);
2398 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2399 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2400 IUnknown_Release(element);
2402 hr = IMFCollection_GetElement(collection, 1, &element);
2403 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2404 ok(!element, "Unexpected element.\n");
2406 hr = IMFCollection_GetElement(collection, 2, &element);
2407 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2408 ok(!element, "Unexpected element.\n");
2410 hr = IMFCollection_GetElement(collection, 10, &element);
2411 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2412 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2413 IUnknown_Release(element);
2415 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2416 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2418 hr = IMFCollection_GetElement(collection, 0, &element);
2419 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2421 hr = IMFCollection_RemoveAllElements(collection);
2422 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2424 count = 1;
2425 hr = IMFCollection_GetElementCount(collection, &count);
2426 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2427 ok(count == 0, "Unexpected count %u.\n", count);
2429 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2430 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2432 IMFCollection_Release(collection);
2435 static void test_MFHeapAlloc(void)
2437 void *res;
2439 if (!pMFHeapAlloc)
2441 win_skip("MFHeapAlloc() is not available.\n");
2442 return;
2445 res = pMFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2446 ok(res != NULL, "MFHeapAlloc failed.\n");
2448 pMFHeapFree(res);
2451 static void test_scheduled_items(void)
2453 struct test_callback callback;
2454 IMFAsyncResult *result;
2455 MFWORKITEM_KEY key, key2;
2456 HRESULT hr;
2458 init_test_callback(&callback);
2460 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2461 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2463 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2464 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2466 hr = MFCancelWorkItem(key);
2467 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2469 hr = MFCancelWorkItem(key);
2470 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2472 if (!pMFPutWaitingWorkItem)
2474 win_skip("Waiting items are not supported.\n");
2475 return;
2478 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2479 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2481 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2482 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2484 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2485 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2487 hr = MFCancelWorkItem(key);
2488 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2490 hr = MFCancelWorkItem(key2);
2491 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2493 IMFAsyncResult_Release(result);
2495 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2496 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2498 hr = MFCancelWorkItem(key);
2499 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2501 hr = MFShutdown();
2502 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2505 static void test_serial_queue(void)
2507 static const DWORD queue_ids[] =
2509 MFASYNC_CALLBACK_QUEUE_STANDARD,
2510 MFASYNC_CALLBACK_QUEUE_RT,
2511 MFASYNC_CALLBACK_QUEUE_IO,
2512 MFASYNC_CALLBACK_QUEUE_TIMER,
2513 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2514 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2516 DWORD queue, serial_queue;
2517 unsigned int i;
2518 HRESULT hr;
2520 if (!pMFAllocateSerialWorkQueue)
2522 win_skip("Serial queues are not supported.\n");
2523 return;
2526 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2527 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2529 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2531 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2532 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2534 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2535 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2536 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2538 if (SUCCEEDED(hr))
2540 hr = MFUnlockWorkQueue(serial_queue);
2541 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2545 /* Chain them together. */
2546 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2547 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2549 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2550 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2552 hr = MFUnlockWorkQueue(serial_queue);
2553 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2555 hr = MFUnlockWorkQueue(queue);
2556 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2558 hr = MFShutdown();
2559 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2562 static LONG periodic_counter;
2563 static void CALLBACK periodic_callback(IUnknown *context)
2565 InterlockedIncrement(&periodic_counter);
2568 static void test_periodic_callback(void)
2570 DWORD period, key;
2571 HRESULT hr;
2573 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2574 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2576 period = 0;
2577 hr = MFGetTimerPeriodicity(&period);
2578 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2579 ok(period == 10, "Unexpected period %u.\n", period);
2581 if (!pMFAddPeriodicCallback)
2583 win_skip("Periodic callbacks are not supported.\n");
2584 hr = MFShutdown();
2585 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2586 return;
2589 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2591 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2592 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2593 ok(key != 0, "Unexpected key %#x.\n", key);
2595 Sleep(10 * period);
2597 hr = pMFRemovePeriodicCallback(key);
2598 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2600 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2602 hr = MFShutdown();
2603 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2606 static void test_event_queue(void)
2608 struct test_callback callback, callback2;
2609 IMFMediaEvent *event, *event2;
2610 IMFMediaEventQueue *queue;
2611 IMFAsyncResult *result;
2612 HRESULT hr;
2613 DWORD ret;
2615 init_test_callback(&callback);
2616 init_test_callback(&callback2);
2618 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2619 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2621 hr = MFCreateEventQueue(&queue);
2622 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
2624 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2625 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2627 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2628 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2630 if (is_win8_plus)
2632 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2633 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2635 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
2636 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2637 ok(event2 == event, "Unexpected event object.\n");
2638 IMFMediaEvent_Release(event2);
2640 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2641 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2643 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
2644 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2645 IMFMediaEvent_Release(event2);
2648 /* Async case. */
2649 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2650 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2652 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2653 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
2655 /* Same callback, same state. */
2656 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2657 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2659 /* Same callback, different state. */
2660 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
2661 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2663 /* Different callback, same state. */
2664 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
2665 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2667 /* Different callback, different state. */
2668 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
2669 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2671 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
2673 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2674 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2676 ret = WaitForSingleObject(callback.event, 100);
2677 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
2679 CloseHandle(callback.event);
2681 IMFMediaEvent_Release(event);
2683 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2684 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2686 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2687 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
2689 /* Shutdown behavior. */
2690 hr = IMFMediaEventQueue_Shutdown(queue);
2691 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2693 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2694 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2696 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2697 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2698 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2699 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2700 IMFMediaEvent_Release(event);
2702 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2703 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2705 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2706 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2708 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
2709 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2711 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2712 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2714 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2715 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2716 IMFAsyncResult_Release(result);
2718 /* Already shut down. */
2719 hr = IMFMediaEventQueue_Shutdown(queue);
2720 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2722 IMFMediaEventQueue_Release(queue);
2724 hr = MFShutdown();
2725 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2728 static void test_presentation_descriptor(void)
2730 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
2731 IMFPresentationDescriptor *pd, *pd2;
2732 IMFMediaType *media_type;
2733 unsigned int i;
2734 BOOL selected;
2735 UINT64 value;
2736 DWORD count;
2737 HRESULT hr;
2739 hr = MFCreateMediaType(&media_type);
2740 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2742 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
2744 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
2745 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
2748 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
2749 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
2751 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
2752 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
2754 for (i = 0; i < count; ++i)
2756 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
2757 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2758 ok(!selected, "Unexpected selected state.\n");
2759 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
2760 IMFStreamDescriptor_Release(stream_desc2);
2763 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
2764 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2766 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
2767 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2769 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
2770 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
2772 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
2773 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2774 ok(!!selected, "Unexpected selected state.\n");
2775 IMFStreamDescriptor_Release(stream_desc2);
2777 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
2778 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2780 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
2781 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
2783 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
2784 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2785 ok(!!selected, "Unexpected selected state.\n");
2786 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
2787 IMFStreamDescriptor_Release(stream_desc2);
2789 value = 0;
2790 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
2791 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2792 ok(value == 1, "Unexpected attribute value.\n");
2794 IMFPresentationDescriptor_Release(pd2);
2795 IMFPresentationDescriptor_Release(pd);
2797 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
2799 IMFStreamDescriptor_Release(stream_desc[i]);
2802 /* Partially initialized array. */
2803 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
2804 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
2805 stream_desc[0] = NULL;
2807 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
2808 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2810 IMFStreamDescriptor_Release(stream_desc[1]);
2811 IMFMediaType_Release(media_type);
2814 enum clock_action
2816 CLOCK_START,
2817 CLOCK_STOP,
2818 CLOCK_PAUSE,
2819 CLOCK_RESTART,
2822 static void test_system_time_source(void)
2824 static const struct clock_state_test
2826 enum clock_action action;
2827 MFCLOCK_STATE state;
2828 BOOL is_invalid;
2830 clock_state_change[] =
2832 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
2833 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
2834 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2835 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
2836 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2837 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2838 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
2839 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2840 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2841 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
2842 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2843 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2844 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2845 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
2846 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
2847 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2848 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
2850 IMFPresentationTimeSource *time_source, *time_source2;
2851 IMFClockStateSink *statesink;
2852 IMFClock *clock, *clock2;
2853 MFCLOCK_PROPERTIES props;
2854 MFCLOCK_STATE state;
2855 unsigned int i;
2856 MFTIME systime;
2857 LONGLONG time;
2858 DWORD value;
2859 HRESULT hr;
2861 hr = MFCreateSystemTimeSource(&time_source);
2862 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2864 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
2865 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
2866 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
2867 "Unexpected flags %#x.\n", value);
2869 value = 1;
2870 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
2871 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2872 ok(value == 0, "Unexpected value %u.\n", value);
2874 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2875 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
2876 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
2878 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
2879 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
2881 /* State changes. */
2882 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
2884 switch (clock_state_change[i].action)
2886 case CLOCK_STOP:
2887 hr = IMFClockStateSink_OnClockStop(statesink, 0);
2888 break;
2889 case CLOCK_RESTART:
2890 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
2891 break;
2892 case CLOCK_PAUSE:
2893 hr = IMFClockStateSink_OnClockPause(statesink, 0);
2894 break;
2895 case CLOCK_START:
2896 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
2897 break;
2898 default:
2901 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
2902 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2903 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
2904 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
2907 IMFClockStateSink_Release(statesink);
2909 /* Properties. */
2910 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
2911 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2913 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
2914 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
2916 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
2917 wine_dbgstr_longlong(props.qwCorrelationRate));
2918 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
2919 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
2920 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
2921 wine_dbgstr_longlong(props.qwClockFrequency));
2922 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
2923 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
2925 /* Underlying clock. */
2926 hr = MFCreateSystemTimeSource(&time_source2);
2927 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2928 EXPECT_REF(time_source2, 1);
2929 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
2930 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2931 EXPECT_REF(time_source2, 1);
2932 EXPECT_REF(clock2, 2);
2934 EXPECT_REF(time_source, 1);
2935 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
2936 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2937 EXPECT_REF(time_source, 1);
2938 EXPECT_REF(clock, 2);
2940 ok(clock != clock2, "Unexpected clock instance.\n");
2942 IMFPresentationTimeSource_Release(time_source2);
2943 IMFClock_Release(clock2);
2945 hr = IMFClock_GetClockCharacteristics(clock, &value);
2946 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
2947 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
2948 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
2950 hr = IMFClock_GetContinuityKey(clock, &value);
2951 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
2952 ok(value == 0, "Unexpected key value %u.\n", value);
2954 hr = IMFClock_GetState(clock, 0, &state);
2955 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2956 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
2958 hr = IMFClock_GetProperties(clock, &props);
2959 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
2961 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
2962 wine_dbgstr_longlong(props.qwCorrelationRate));
2963 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
2964 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
2965 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
2966 wine_dbgstr_longlong(props.qwClockFrequency));
2967 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
2968 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
2970 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
2971 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
2972 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2974 IMFClock_Release(clock);
2976 /* Test returned time regarding specified rate and offset. */
2977 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
2978 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
2980 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2981 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
2982 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
2984 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2985 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2986 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2988 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
2989 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2991 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2992 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2993 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2995 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
2996 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2998 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2999 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3000 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3001 wine_dbgstr_longlong(systime));
3003 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3004 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3006 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3007 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3008 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3010 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3011 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3013 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3014 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3015 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3016 wine_dbgstr_longlong(systime));
3018 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3019 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3021 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3022 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3023 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3024 wine_dbgstr_longlong(systime));
3026 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3027 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3029 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3030 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3031 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3033 /* Increased rate. */
3034 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3035 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
3037 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3038 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3040 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3041 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3042 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3043 wine_dbgstr_longlong(2 * systime));
3045 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3046 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3048 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3049 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3050 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3051 wine_dbgstr_longlong(2 * systime));
3053 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3054 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3056 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3057 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3058 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3059 wine_dbgstr_longlong(systime));
3061 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3062 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3064 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3065 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3066 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3067 wine_dbgstr_longlong(systime));
3069 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3070 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3072 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3073 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3074 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3075 wine_dbgstr_longlong(systime));
3077 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3078 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3080 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3081 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3082 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3083 IMFClockStateSink_Release(statesink);
3085 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3086 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3088 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3089 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3090 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3091 wine_dbgstr_longlong(2 * systime));
3093 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3094 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3096 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3097 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3099 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3100 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3101 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3102 wine_dbgstr_longlong(2 * systime));
3104 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3105 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3107 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3108 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3109 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3110 wine_dbgstr_longlong(systime));
3112 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3113 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3115 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3116 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3117 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3118 wine_dbgstr_longlong(systime));
3120 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3121 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3123 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3124 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3125 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3126 wine_dbgstr_longlong(systime));
3128 IMFPresentationTimeSource_Release(time_source);
3131 static void test_MFInvokeCallback(void)
3133 struct test_callback callback;
3134 IMFAsyncResult *result;
3135 MFASYNCRESULT *data;
3136 ULONG refcount;
3137 HRESULT hr;
3138 DWORD ret;
3140 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3141 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3143 init_test_callback(&callback);
3145 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3146 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3148 data = (MFASYNCRESULT *)result;
3149 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3150 ok(data->hEvent != NULL, "Failed to create event.\n");
3152 hr = MFInvokeCallback(result);
3153 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
3155 ret = WaitForSingleObject(data->hEvent, 100);
3156 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
3158 refcount = IMFAsyncResult_Release(result);
3159 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3161 hr = MFShutdown();
3162 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3165 static void test_stream_descriptor(void)
3167 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3168 IMFMediaTypeHandler *type_handler;
3169 IMFStreamDescriptor *stream_desc;
3170 GUID major_type;
3171 DWORD id, count;
3172 unsigned int i;
3173 HRESULT hr;
3175 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3176 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3178 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3180 hr = MFCreateMediaType(&media_types[i]);
3181 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3184 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3185 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3187 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3188 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3190 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3191 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
3192 ok(id == 123, "Unexpected id %#x.\n", id);
3194 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3195 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3197 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3198 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3199 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3201 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3202 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3204 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3205 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3207 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3209 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3210 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3211 ok(media_type == media_types[i], "Unexpected object.\n");
3213 if (SUCCEEDED(hr))
3214 IMFMediaType_Release(media_type);
3217 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
3218 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3220 /* IsMediaTypeSupported() */
3222 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3223 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3225 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
3226 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3228 hr = MFCreateMediaType(&media_type);
3229 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3231 hr = MFCreateMediaType(&media_type3);
3232 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3234 media_type2 = (void *)0xdeadbeef;
3235 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3236 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3237 ok(!media_type2, "Unexpected pointer.\n");
3239 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3240 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3242 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3243 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3245 media_type2 = (void *)0xdeadbeef;
3246 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3247 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3248 ok(!media_type2, "Unexpected pointer.\n");
3250 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3251 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3253 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3254 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3256 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3257 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3258 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
3260 /* Mismatching major types. */
3261 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3262 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3264 media_type2 = (void *)0xdeadbeef;
3265 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3266 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3267 ok(!media_type2, "Unexpected pointer.\n");
3269 /* Subtype missing. */
3270 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3271 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3273 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3274 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3276 media_type2 = (void *)0xdeadbeef;
3277 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3278 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3279 ok(!media_type2, "Unexpected pointer.\n");
3281 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3282 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3284 media_type2 = (void *)0xdeadbeef;
3285 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3286 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3287 ok(!media_type2, "Unexpected pointer.\n");
3289 /* Mismatching subtype. */
3290 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3291 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3293 media_type2 = (void *)0xdeadbeef;
3294 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3295 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3296 ok(!media_type2, "Unexpected pointer.\n");
3298 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3299 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3300 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3302 IMFMediaTypeHandler_Release(type_handler);
3303 IMFStreamDescriptor_Release(stream_desc);
3305 /* IsMediaTypeSupported() for unset current type. */
3306 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3307 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3309 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3310 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3312 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
3313 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3315 /* Initialize one from initial type set. */
3316 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
3317 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3319 media_type2 = (void *)0xdeadbeef;
3320 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3321 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3322 ok(!media_type2, "Unexpected pointer.\n");
3324 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3325 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3327 media_type2 = (void *)0xdeadbeef;
3328 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3329 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3330 ok(!media_type2, "Unexpected pointer.\n");
3332 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3333 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3335 media_type2 = (void *)0xdeadbeef;
3336 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3337 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3338 ok(!media_type2, "Unexpected pointer.\n");
3340 /* Now set current type that's not compatible. */
3341 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3342 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3344 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3345 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3347 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
3348 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3350 media_type2 = (void *)0xdeadbeef;
3351 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3352 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3353 ok(!media_type2, "Unexpected pointer.\n");
3355 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
3356 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3358 media_type2 = (void *)0xdeadbeef;
3359 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3360 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3361 ok(!media_type2, "Unexpected pointer.\n");
3363 IMFMediaType_Release(media_type);
3364 IMFMediaType_Release(media_type3);
3366 IMFMediaTypeHandler_Release(type_handler);
3368 IMFStreamDescriptor_Release(stream_desc);
3371 static void test_MFCalculateImageSize(void)
3373 static const struct image_size_test
3375 const GUID *subtype;
3376 UINT32 width;
3377 UINT32 height;
3378 UINT32 size;
3380 image_size_tests[] =
3382 { &MFVideoFormat_RGB8, 3, 5, 20 },
3383 { &MFVideoFormat_RGB8, 1, 1, 4 },
3384 { &MFVideoFormat_RGB555, 3, 5, 40 },
3385 { &MFVideoFormat_RGB555, 1, 1, 4 },
3386 { &MFVideoFormat_RGB565, 3, 5, 40 },
3387 { &MFVideoFormat_RGB565, 1, 1, 4 },
3388 { &MFVideoFormat_RGB24, 3, 5, 60 },
3389 { &MFVideoFormat_RGB24, 1, 1, 4 },
3390 { &MFVideoFormat_RGB32, 3, 5, 60 },
3391 { &MFVideoFormat_RGB32, 1, 1, 4 },
3392 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3393 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3394 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3395 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3396 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3397 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3399 unsigned int i;
3400 UINT32 size;
3401 HRESULT hr;
3403 if (!pMFGetPlaneSize)
3404 win_skip("MFGetPlaneSize() is not available.\n");
3406 size = 1;
3407 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
3408 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
3409 ok(size == 0, "Unexpected size %u.\n", size);
3411 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
3413 /* Those are supported since Win10. */
3414 BOOL is_broken = IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A16B16G16R16F) ||
3415 IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A2R10G10B10);
3417 hr = MFCalculateImageSize(image_size_tests[i].subtype, image_size_tests[i].width,
3418 image_size_tests[i].height, &size);
3419 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
3420 ok(size == image_size_tests[i].size, "%u: unexpected image size %u, expected %u.\n", i, size,
3421 image_size_tests[i].size);
3423 if (pMFGetPlaneSize)
3425 hr = pMFGetPlaneSize(image_size_tests[i].subtype->Data1, image_size_tests[i].width, image_size_tests[i].height,
3426 &size);
3427 ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
3428 ok(size == image_size_tests[i].size, "%u: unexpected plane size %u, expected %u.\n", i, size,
3429 image_size_tests[i].size);
3434 static void test_MFCompareFullToPartialMediaType(void)
3436 IMFMediaType *full_type, *partial_type;
3437 HRESULT hr;
3438 BOOL ret;
3440 hr = MFCreateMediaType(&full_type);
3441 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3443 hr = MFCreateMediaType(&partial_type);
3444 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3446 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3447 ok(!ret, "Unexpected result %d.\n", ret);
3449 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3450 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3452 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3453 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3455 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3456 ok(ret, "Unexpected result %d.\n", ret);
3458 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
3459 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3461 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3462 ok(ret, "Unexpected result %d.\n", ret);
3464 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
3465 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3467 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3468 ok(!ret, "Unexpected result %d.\n", ret);
3470 IMFMediaType_Release(full_type);
3471 IMFMediaType_Release(partial_type);
3474 static void test_attributes_serialization(void)
3476 static const UINT8 blob[] = {1,2,3};
3477 IMFAttributes *attributes, *dest;
3478 UINT32 size, count, value32;
3479 double value_dbl;
3480 UINT64 value64;
3481 UINT8 *buffer;
3482 IUnknown *obj;
3483 HRESULT hr;
3484 WCHAR *str;
3485 GUID guid;
3487 hr = MFCreateAttributes(&attributes, 0);
3488 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3490 hr = MFCreateAttributes(&dest, 0);
3491 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3493 hr = MFGetAttributesAsBlobSize(attributes, &size);
3494 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3495 ok(size == 8, "Got size %u.\n", size);
3497 buffer = heap_alloc(size);
3499 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3500 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3502 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
3503 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
3505 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
3506 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3508 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
3509 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3511 hr = MFInitAttributesFromBlob(dest, buffer, size);
3512 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3514 /* Previous items are cleared. */
3515 hr = IMFAttributes_GetCount(dest, &count);
3516 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3517 ok(count == 0, "Unexpected count %u.\n", count);
3519 heap_free(buffer);
3521 /* Set some attributes of various types. */
3522 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
3523 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
3524 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
3525 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
3526 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
3527 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
3528 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
3530 hr = MFGetAttributesAsBlobSize(attributes, &size);
3531 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3532 ok(size > 8, "Got unexpected size %u.\n", size);
3534 buffer = heap_alloc(size);
3535 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3536 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3537 hr = MFInitAttributesFromBlob(dest, buffer, size);
3538 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3539 heap_free(buffer);
3541 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
3542 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
3543 ok(value32 == 456, "Unexpected value %u.\n", value32);
3544 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
3545 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
3546 ok(value64 == 123, "Unexpected value.\n");
3547 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
3548 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
3549 ok(value_dbl == 0.5, "Unexpected value.\n");
3550 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
3551 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3552 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
3553 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
3554 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
3555 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
3556 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
3557 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
3558 CoTaskMemFree(str);
3559 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
3560 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
3561 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
3562 CoTaskMemFree(buffer);
3564 IMFAttributes_Release(attributes);
3565 IMFAttributes_Release(dest);
3568 static void test_wrapped_media_type(void)
3570 IMFMediaType *mediatype, *mediatype2;
3571 UINT32 count, type;
3572 HRESULT hr;
3573 GUID guid;
3575 hr = MFCreateMediaType(&mediatype);
3576 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3578 hr = MFUnwrapMediaType(mediatype, &mediatype2);
3579 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3581 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
3582 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3583 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
3584 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3586 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3587 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
3589 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
3590 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
3592 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
3593 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3594 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
3596 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
3597 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
3598 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
3600 hr = IMFMediaType_GetCount(mediatype2, &count);
3601 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
3602 ok(count == 3, "Unexpected count %u.\n", count);
3604 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
3605 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
3606 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
3608 IMFMediaType_Release(mediatype);
3610 hr = MFUnwrapMediaType(mediatype2, &mediatype);
3611 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
3613 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
3614 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3615 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
3617 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
3618 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3620 IMFMediaType_Release(mediatype);
3621 IMFMediaType_Release(mediatype2);
3624 static void test_MFCreateWaveFormatExFromMFMediaType(void)
3626 WAVEFORMATEXTENSIBLE *format_ext;
3627 IMFMediaType *mediatype;
3628 WAVEFORMATEX *format;
3629 UINT32 size;
3630 HRESULT hr;
3632 hr = MFCreateMediaType(&mediatype);
3633 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3635 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3636 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3638 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3639 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3641 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3642 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3644 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
3645 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3647 /* Audio/PCM */
3648 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3649 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3650 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3651 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3653 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3654 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3655 ok(format != NULL, "Expected format structure.\n");
3656 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
3657 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
3658 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
3659 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
3660 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
3661 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
3662 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
3663 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
3664 CoTaskMemFree(format);
3666 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
3667 MFWaveFormatExConvertFlag_ForceExtensible);
3668 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3669 ok(format_ext != NULL, "Expected format structure.\n");
3670 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
3671 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
3672 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
3673 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
3674 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
3675 format_ext->Format.nAvgBytesPerSec);
3676 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
3677 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
3678 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
3679 format_ext->Format.cbSize);
3680 CoTaskMemFree(format_ext);
3682 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
3683 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3684 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
3685 CoTaskMemFree(format);
3687 IMFMediaType_Release(mediatype);
3690 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
3692 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
3693 IMFByteStream *stream;
3694 IUnknown *object;
3695 HRESULT hr;
3697 ok(!!result, "Unexpected result object.\n");
3699 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
3701 hr = IMFAsyncResult_GetObject(result, &object);
3702 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3704 hr = MFEndCreateFile(result, &stream);
3705 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
3706 IMFByteStream_Release(stream);
3708 SetEvent(callback->event);
3710 return S_OK;
3713 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
3715 testcallback_QueryInterface,
3716 testcallback_AddRef,
3717 testcallback_Release,
3718 testcallback_GetParameters,
3719 test_create_file_callback_Invoke,
3722 static void test_async_create_file(void)
3724 struct test_callback callback = { { &test_create_file_callback_vtbl } };
3725 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
3726 IUnknown *cancel_cookie;
3727 HRESULT hr;
3728 BOOL ret;
3730 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3731 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
3733 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
3735 GetTempPathW(ARRAY_SIZE(pathW), pathW);
3736 GetTempFileNameW(pathW, NULL, 0, fileW);
3738 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
3739 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
3740 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
3741 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
3743 WaitForSingleObject(callback.event, INFINITE);
3745 IUnknown_Release(cancel_cookie);
3747 CloseHandle(callback.event);
3749 hr = MFShutdown();
3750 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3752 ret = DeleteFileW(fileW);
3753 ok(ret, "Failed to delete test file.\n");
3756 struct activate_object
3758 IMFActivate IMFActivate_iface;
3759 LONG refcount;
3762 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
3764 if (IsEqualIID(riid, &IID_IMFActivate) ||
3765 IsEqualIID(riid, &IID_IMFAttributes) ||
3766 IsEqualIID(riid, &IID_IUnknown))
3768 *obj = iface;
3769 IMFActivate_AddRef(iface);
3770 return S_OK;
3773 *obj = NULL;
3774 return E_NOINTERFACE;
3777 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
3779 return 2;
3782 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
3784 return 1;
3787 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
3789 return E_NOTIMPL;
3792 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
3794 return E_NOTIMPL;
3797 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
3799 return E_NOTIMPL;
3802 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
3803 BOOL *result)
3805 return E_NOTIMPL;
3808 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
3810 return E_NOTIMPL;
3813 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
3815 return E_NOTIMPL;
3818 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
3820 return E_NOTIMPL;
3823 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
3825 return E_NOTIMPL;
3828 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
3830 return E_NOTIMPL;
3833 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
3834 UINT32 size, UINT32 *length)
3836 return E_NOTIMPL;
3839 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
3840 WCHAR **value, UINT32 *length)
3842 return E_NOTIMPL;
3845 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
3847 return E_NOTIMPL;
3850 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
3851 UINT32 bufsize, UINT32 *blobsize)
3853 return E_NOTIMPL;
3856 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
3858 return E_NOTIMPL;
3861 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
3863 return E_NOTIMPL;
3866 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
3868 return E_NOTIMPL;
3871 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
3873 return E_NOTIMPL;
3876 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
3878 return E_NOTIMPL;
3881 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
3883 return E_NOTIMPL;
3886 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
3888 return E_NOTIMPL;
3891 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
3893 return E_NOTIMPL;
3896 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
3898 return E_NOTIMPL;
3901 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
3903 return E_NOTIMPL;
3906 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
3908 return E_NOTIMPL;
3911 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
3913 return E_NOTIMPL;
3916 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
3918 return E_NOTIMPL;
3921 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
3923 return E_NOTIMPL;
3926 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
3928 return E_NOTIMPL;
3931 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
3933 return E_NOTIMPL;
3936 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
3938 return E_NOTIMPL;
3941 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
3943 return E_NOTIMPL;
3946 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
3948 return E_NOTIMPL;
3951 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
3953 return E_NOTIMPL;
3956 static const IMFActivateVtbl activate_object_vtbl =
3958 activate_object_QueryInterface,
3959 activate_object_AddRef,
3960 activate_object_Release,
3961 activate_object_GetItem,
3962 activate_object_GetItemType,
3963 activate_object_CompareItem,
3964 activate_object_Compare,
3965 activate_object_GetUINT32,
3966 activate_object_GetUINT64,
3967 activate_object_GetDouble,
3968 activate_object_GetGUID,
3969 activate_object_GetStringLength,
3970 activate_object_GetString,
3971 activate_object_GetAllocatedString,
3972 activate_object_GetBlobSize,
3973 activate_object_GetBlob,
3974 activate_object_GetAllocatedBlob,
3975 activate_object_GetUnknown,
3976 activate_object_SetItem,
3977 activate_object_DeleteItem,
3978 activate_object_DeleteAllItems,
3979 activate_object_SetUINT32,
3980 activate_object_SetUINT64,
3981 activate_object_SetDouble,
3982 activate_object_SetGUID,
3983 activate_object_SetString,
3984 activate_object_SetBlob,
3985 activate_object_SetUnknown,
3986 activate_object_LockStore,
3987 activate_object_UnlockStore,
3988 activate_object_GetCount,
3989 activate_object_GetItemByIndex,
3990 activate_object_CopyAllItems,
3991 activate_object_ActivateObject,
3992 activate_object_ShutdownObject,
3993 activate_object_DetachObject,
3996 static void test_local_handlers(void)
3998 IMFActivate local_activate = { &activate_object_vtbl };
3999 static const WCHAR localW[] = L"local";
4000 HRESULT hr;
4002 if (!pMFRegisterLocalSchemeHandler)
4004 win_skip("Local handlers are not supported.\n");
4005 return;
4008 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4009 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4011 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4012 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4014 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4015 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4017 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4018 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4020 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4021 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4023 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4024 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4026 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4027 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4029 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4030 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4032 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4033 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4035 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4036 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4039 static void test_create_property_store(void)
4041 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4042 IPropertyStore *store, *store2;
4043 PROPVARIANT value = {0};
4044 PROPERTYKEY key;
4045 ULONG refcount;
4046 IUnknown *unk;
4047 DWORD count;
4048 HRESULT hr;
4050 hr = CreatePropertyStore(NULL);
4051 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4053 hr = CreatePropertyStore(&store);
4054 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4056 hr = CreatePropertyStore(&store2);
4057 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4058 ok(store2 != store, "Expected different store objects.\n");
4059 IPropertyStore_Release(store2);
4061 hr = IPropertyStore_QueryInterface(store, &IID_IPropertyStoreCache, (void **)&unk);
4062 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
4063 hr = IPropertyStore_QueryInterface(store, &IID_IPersistSerializedPropStorage, (void **)&unk);
4064 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
4066 hr = IPropertyStore_GetCount(store, NULL);
4067 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4069 count = 0xdeadbeef;
4070 hr = IPropertyStore_GetCount(store, &count);
4071 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4072 ok(!count, "Unexpected count %u.\n", count);
4074 hr = IPropertyStore_Commit(store);
4075 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4077 hr = IPropertyStore_GetAt(store, 0, &key);
4078 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4080 hr = IPropertyStore_GetValue(store, NULL, &value);
4081 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4083 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
4084 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4086 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4087 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4089 memset(&value, 0, sizeof(PROPVARIANT));
4090 value.vt = VT_I4;
4091 value.lVal = 0xdeadbeef;
4092 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4093 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4095 if (0)
4097 /* crashes on Windows */
4098 hr = IPropertyStore_SetValue(store, NULL, &value);
4099 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4102 hr = IPropertyStore_GetCount(store, &count);
4103 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4104 ok(count == 1, "Unexpected count %u.\n", count);
4106 hr = IPropertyStore_Commit(store);
4107 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4109 hr = IPropertyStore_GetAt(store, 0, &key);
4110 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4111 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
4113 hr = IPropertyStore_GetAt(store, 1, &key);
4114 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4116 memset(&value, 0xcc, sizeof(PROPVARIANT));
4117 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4118 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4119 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
4120 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
4122 memset(&value, 0, sizeof(PROPVARIANT));
4123 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4124 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4126 hr = IPropertyStore_GetCount(store, &count);
4127 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4128 ok(count == 1, "Unexpected count %u.\n", count);
4130 memset(&value, 0xcc, sizeof(PROPVARIANT));
4131 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4132 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4133 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
4134 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
4136 refcount = IPropertyStore_Release(store);
4137 ok(!refcount, "Unexpected refcount %u.\n", refcount);
4140 static void test_dxgi_device_manager(void)
4142 IMFDXGIDeviceManager *manager, *manager2;
4143 ID3D11Device *d3d11_dev, *d3d11_dev2;
4144 UINT token, token2;
4145 HRESULT hr;
4147 if (!pMFCreateDXGIDeviceManager)
4149 win_skip("MFCreateDXGIDeviceManager not found.\n");
4150 return;
4153 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
4154 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4156 token = 0;
4157 hr = pMFCreateDXGIDeviceManager(&token, NULL);
4158 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4159 ok(!token, "got wrong token: %u.\n", token);
4161 hr = pMFCreateDXGIDeviceManager(&token, &manager);
4162 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4163 EXPECT_REF(manager, 1);
4164 ok(!!token, "got wrong token: %u.\n", token);
4166 Sleep(50);
4167 token2 = 0;
4168 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
4169 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4170 EXPECT_REF(manager2, 1);
4171 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
4172 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
4173 EXPECT_REF(manager, 1);
4175 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
4176 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
4177 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4178 EXPECT_REF(d3d11_dev, 1);
4180 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
4181 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4182 EXPECT_REF(d3d11_dev, 1);
4184 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
4185 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4187 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4188 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4189 EXPECT_REF(manager, 1);
4190 EXPECT_REF(d3d11_dev, 2);
4192 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
4193 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4194 EXPECT_REF(manager2, 1);
4195 EXPECT_REF(d3d11_dev, 2);
4197 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4198 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4199 EXPECT_REF(manager, 1);
4200 EXPECT_REF(d3d11_dev, 2);
4202 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
4203 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
4204 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4205 EXPECT_REF(d3d11_dev2, 1);
4206 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
4207 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4208 EXPECT_REF(manager, 1);
4209 EXPECT_REF(d3d11_dev2, 2);
4210 EXPECT_REF(d3d11_dev, 1);
4212 IMFDXGIDeviceManager_Release(manager);
4213 EXPECT_REF(d3d11_dev2, 1);
4214 ID3D11Device_Release(d3d11_dev);
4215 ID3D11Device_Release(d3d11_dev2);
4216 IMFDXGIDeviceManager_Release(manager2);
4219 static void test_MFCreateTransformActivate(void)
4221 IMFActivate *activate;
4222 UINT32 count;
4223 HRESULT hr;
4225 if (!pMFCreateTransformActivate)
4227 win_skip("MFCreateTransformActivate() is not available.\n");
4228 return;
4231 hr = pMFCreateTransformActivate(&activate);
4232 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
4234 hr = IMFActivate_GetCount(activate, &count);
4235 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4236 ok(!count, "Unexpected attribute count %u.\n", count);
4238 IMFActivate_Release(activate);
4241 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
4243 if (IsEqualIID(riid, &IID_IClassFactory) ||
4244 IsEqualIID(riid, &IID_IUnknown))
4246 *obj = iface;
4247 IClassFactory_AddRef(iface);
4248 return S_OK;
4251 *obj = NULL;
4252 return E_NOINTERFACE;
4255 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
4257 return 2;
4260 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
4262 return 1;
4265 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
4267 ok(0, "Unexpected call.\n");
4268 return E_NOTIMPL;
4271 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
4273 return S_OK;
4276 static const IClassFactoryVtbl test_mft_factory_vtbl =
4278 test_mft_factory_QueryInterface,
4279 test_mft_factory_AddRef,
4280 test_mft_factory_Release,
4281 test_mft_factory_CreateInstance,
4282 test_mft_factory_LockServer,
4285 static void test_MFTRegisterLocal(void)
4287 IClassFactory test_factory = { &test_mft_factory_vtbl };
4288 MFT_REGISTER_TYPE_INFO input_types[1];
4289 IMFActivate **activate;
4290 UINT32 count, count2;
4291 HRESULT hr;
4293 if (!pMFTRegisterLocal)
4295 win_skip("MFTRegisterLocal() is not available.\n");
4296 return;
4299 input_types[0].guidMajorType = MFMediaType_Audio;
4300 input_types[0].guidSubtype = MFAudioFormat_PCM;
4301 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
4302 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4304 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
4305 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4307 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
4308 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4309 ok(count > 0, "Unexpected count %u.\n", count);
4310 CoTaskMemFree(activate);
4312 hr = pMFTUnregisterLocal(&test_factory);
4313 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
4315 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
4316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4317 ok(count2 < count, "Unexpected count %u.\n", count2);
4318 CoTaskMemFree(activate);
4320 hr = pMFTUnregisterLocal(&test_factory);
4321 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
4323 hr = pMFTUnregisterLocal(NULL);
4324 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4326 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
4327 0, NULL);
4328 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4330 hr = pMFTUnregisterLocal(NULL);
4331 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4333 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
4334 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
4336 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
4337 0, NULL);
4338 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4340 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
4341 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4344 static void test_queue_com(void)
4346 static int system_queues[] =
4348 MFASYNC_CALLBACK_QUEUE_STANDARD,
4349 MFASYNC_CALLBACK_QUEUE_RT,
4350 MFASYNC_CALLBACK_QUEUE_IO,
4351 MFASYNC_CALLBACK_QUEUE_TIMER,
4352 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
4353 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
4356 static int user_queues[] =
4358 MF_STANDARD_WORKQUEUE,
4359 MF_WINDOW_WORKQUEUE,
4360 MF_MULTITHREADED_WORKQUEUE,
4363 char path_name[MAX_PATH];
4364 PROCESS_INFORMATION info;
4365 STARTUPINFOA startup;
4366 char **argv;
4367 int i;
4369 if (!pCoGetApartmentType)
4371 win_skip("CoGetApartmentType() is not available.\n");
4372 return;
4375 winetest_get_mainargs(&argv);
4377 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
4379 memset(&startup, 0, sizeof(startup));
4380 startup.cb = sizeof(startup);
4381 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
4382 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
4383 "CreateProcess failed.\n" );
4384 winetest_wait_child_process(info.hProcess);
4385 CloseHandle(info.hProcess);
4386 CloseHandle(info.hThread);
4389 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
4391 memset(&startup, 0, sizeof(startup));
4392 startup.cb = sizeof(startup);
4393 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
4394 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
4395 "CreateProcess failed.\n" );
4396 winetest_wait_child_process(info.hProcess);
4397 CloseHandle(info.hProcess);
4398 CloseHandle(info.hThread);
4402 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4404 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4405 APTTYPEQUALIFIER qualifier;
4406 APTTYPE com_type;
4407 HRESULT hr;
4409 hr = pCoGetApartmentType(&com_type, &qualifier);
4410 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr);
4411 if (SUCCEEDED(hr))
4413 todo_wine {
4414 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
4415 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
4416 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
4417 else
4418 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
4419 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
4423 SetEvent(callback->event);
4424 return S_OK;
4427 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
4429 testcallback_QueryInterface,
4430 testcallback_AddRef,
4431 testcallback_Release,
4432 testcallback_GetParameters,
4433 test_queue_com_state_callback_Invoke,
4436 static void test_queue_com_state(const char *name)
4438 struct test_callback callback = { { &test_queue_com_state_callback_vtbl } };
4439 DWORD queue, queue_type;
4440 HRESULT hr;
4442 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
4444 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4445 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
4447 if (name[0] == 's')
4449 callback.param = name[1] - '0';
4450 hr = MFPutWorkItem(callback.param, &callback.IMFAsyncCallback_iface, NULL);
4451 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
4452 WaitForSingleObject(callback.event, INFINITE);
4454 else if (name[0] == 'u')
4456 queue_type = name[1] - '0';
4458 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
4459 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
4461 callback.param = queue;
4462 hr = MFPutWorkItem(queue, &callback.IMFAsyncCallback_iface, NULL);
4463 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
4464 WaitForSingleObject(callback.event, INFINITE);
4466 hr = MFUnlockWorkQueue(queue);
4467 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
4470 CloseHandle(callback.event);
4472 hr = MFShutdown();
4473 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4476 START_TEST(mfplat)
4478 char **argv;
4479 int argc;
4481 init_functions();
4483 argc = winetest_get_mainargs(&argv);
4484 if (argc >= 3)
4486 test_queue_com_state(argv[2]);
4487 return;
4490 CoInitialize(NULL);
4492 test_startup();
4493 test_register();
4494 test_media_type();
4495 test_MFCreateMediaEvent();
4496 test_attributes();
4497 test_sample();
4498 test_file_stream();
4499 test_MFCreateMFByteStreamOnStream();
4500 test_system_memory_buffer();
4501 test_source_resolver();
4502 test_MFCreateAsyncResult();
4503 test_allocate_queue();
4504 test_MFCopyImage();
4505 test_MFCreateCollection();
4506 test_MFHeapAlloc();
4507 test_scheduled_items();
4508 test_serial_queue();
4509 test_periodic_callback();
4510 test_event_queue();
4511 test_presentation_descriptor();
4512 test_system_time_source();
4513 test_MFInvokeCallback();
4514 test_stream_descriptor();
4515 test_MFCalculateImageSize();
4516 test_MFCompareFullToPartialMediaType();
4517 test_attributes_serialization();
4518 test_wrapped_media_type();
4519 test_MFCreateWaveFormatExFromMFMediaType();
4520 test_async_create_file();
4521 test_local_handlers();
4522 test_create_property_store();
4523 test_dxgi_device_manager();
4524 test_MFCreateTransformActivate();
4525 test_MFTRegisterLocal();
4526 test_queue_com();
4528 CoUninitialize();