mfplat: Implement IMFByteStream::SetCurrentPosition() for file streams.
[wine.git] / dlls / mfplat / tests / mfplat.c
blob67123d0b69bf81c7cc85fbb4c13bf80aef380ee6
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 *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
67 DWORD width, DWORD lines);
68 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
69 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
70 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
71 static void* (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type);
72 static void (WINAPI *pMFHeapFree)(void *p);
73 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
74 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
75 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
76 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
77 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
78 IMFActivate *activate);
79 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
80 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
81 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
82 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
83 const MFT_REGISTER_TYPE_INFO* output_types);
84 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
85 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
86 const MFT_REGISTER_TYPE_INFO *output_types);
87 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
88 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
90 static const WCHAR mp4file[] = {'t','e','s','t','.','m','p','4',0};
91 static const WCHAR fileschemeW[] = {'f','i','l','e',':','/','/',0};
93 static WCHAR *load_resource(const WCHAR *name)
95 static WCHAR pathW[MAX_PATH];
96 DWORD written;
97 HANDLE file;
98 HRSRC res;
99 void *ptr;
101 GetTempPathW(ARRAY_SIZE(pathW), pathW);
102 lstrcatW(pathW, name);
104 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
105 NULL, CREATE_ALWAYS, 0, 0);
106 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
107 wine_dbgstr_w(pathW), GetLastError());
109 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
110 ok(res != 0, "couldn't find resource\n");
111 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
112 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
113 &written, NULL);
114 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
115 "couldn't write resource\n" );
116 CloseHandle(file);
118 return pathW;
121 struct test_callback
123 IMFAsyncCallback IMFAsyncCallback_iface;
124 HANDLE event;
127 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
129 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
132 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
134 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
135 IsEqualIID(riid, &IID_IUnknown))
137 *obj = iface;
138 IMFAsyncCallback_AddRef(iface);
139 return S_OK;
142 *obj = NULL;
143 return E_NOINTERFACE;
146 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
148 return 2;
151 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
153 return 1;
156 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
158 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
159 return E_NOTIMPL;
163 static BOOL check_clsid(CLSID *clsids, UINT32 count)
165 int i;
166 for (i = 0; i < count; i++)
168 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
169 return TRUE;
171 return FALSE;
174 static void test_register(void)
176 static WCHAR name[] = {'W','i','n','e',' ','t','e','s','t',0};
177 MFT_REGISTER_TYPE_INFO input[] =
179 { DUMMY_CLSID, DUMMY_GUID1 }
181 MFT_REGISTER_TYPE_INFO output[] =
183 { DUMMY_CLSID, DUMMY_GUID2 }
185 CLSID *clsids;
186 UINT32 count;
187 HRESULT ret;
189 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
190 if (ret == E_ACCESSDENIED)
192 win_skip("Not enough permissions to register a filter\n");
193 return;
195 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
197 if(0)
199 /* NULL name crashes on windows */
200 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
201 ok(ret == E_INVALIDARG, "got %x\n", ret);
204 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
205 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
207 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
208 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
210 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
211 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
213 if(0)
215 /* NULL clsids/count crashes on windows (vista) */
216 count = 0;
217 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
218 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
219 ok(count == 0, "Expected count == 0\n");
221 clsids = NULL;
222 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
223 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
226 count = 0;
227 clsids = NULL;
228 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
229 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
230 ok(count > 0, "Expected count > 0\n");
231 ok(clsids != NULL, "Expected clsids != NULL\n");
232 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
233 CoTaskMemFree(clsids);
235 count = 0;
236 clsids = NULL;
237 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
238 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
239 ok(count > 0, "Expected count > 0\n");
240 ok(clsids != NULL, "Expected clsids != NULL\n");
241 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
242 CoTaskMemFree(clsids);
244 count = 0;
245 clsids = NULL;
246 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
247 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
248 ok(count > 0, "Expected count > 0\n");
249 ok(clsids != NULL, "Expected clsids != NULL\n");
250 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
251 CoTaskMemFree(clsids);
253 count = 0;
254 clsids = NULL;
255 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
256 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
257 ok(count > 0, "Expected count > 0\n");
258 ok(clsids != NULL, "Expected clsids != NULL\n");
259 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
260 CoTaskMemFree(clsids);
262 /* exchange input and output */
263 count = 0;
264 clsids = NULL;
265 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
266 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
267 ok(!count, "got %d\n", count);
268 ok(clsids == NULL, "Expected clsids == NULL\n");
270 ret = MFTUnregister(DUMMY_CLSID);
271 ok(ret == S_OK ||
272 /* w7pro64 */
273 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
275 ret = MFTUnregister(DUMMY_CLSID);
276 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
279 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
281 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
282 IMFSourceResolver *resolver;
283 IUnknown *object, *object2;
284 MF_OBJECT_TYPE obj_type;
285 HRESULT hr;
287 ok(!!result, "Unexpected result object.\n");
289 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
291 object = NULL;
292 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
293 todo_wine
294 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
296 hr = IMFAsyncResult_GetObject(result, &object2);
297 ok(hr == S_OK, "Failed to get result object, hr %#x.\n", hr);
298 todo_wine
299 ok(object2 == object, "Unexpected object.\n");
301 if (object)
302 IUnknown_Release(object);
303 IUnknown_Release(object2);
305 SetEvent(callback->event);
307 return S_OK;
310 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
312 testcallback_QueryInterface,
313 testcallback_AddRef,
314 testcallback_Release,
315 testcallback_GetParameters,
316 test_create_from_url_callback_Invoke,
319 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
321 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
322 IMFSchemeHandler *handler;
323 IUnknown *object, *object2;
324 MF_OBJECT_TYPE obj_type;
325 HRESULT hr;
327 ok(!!result, "Unexpected result object.\n");
329 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
331 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
332 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
334 hr = IMFAsyncResult_GetObject(result, &object2);
335 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
337 IUnknown_Release(object);
339 SetEvent(callback->event);
341 return S_OK;
344 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
346 testcallback_QueryInterface,
347 testcallback_AddRef,
348 testcallback_Release,
349 testcallback_GetParameters,
350 test_create_from_file_handler_callback_Invoke,
353 static void test_source_resolver(void)
355 static const WCHAR file_type[] = {'v','i','d','e','o','/','m','p','4',0};
356 struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
357 struct test_callback callback2 = { { &test_create_from_file_handler_callback_vtbl } };
358 IMFSourceResolver *resolver, *resolver2;
359 IMFSchemeHandler *scheme_handler;
360 IMFAttributes *attributes;
361 IMFMediaSource *mediasource;
362 IMFPresentationDescriptor *descriptor;
363 IMFMediaTypeHandler *handler;
364 BOOL selected, do_uninit;
365 MF_OBJECT_TYPE obj_type;
366 IMFStreamDescriptor *sd;
367 IUnknown *cancel_cookie;
368 IMFByteStream *stream;
369 WCHAR pathW[MAX_PATH];
370 HRESULT hr;
371 WCHAR *filename;
372 GUID guid;
374 if (!pMFCreateSourceResolver)
376 win_skip("MFCreateSourceResolver() not found\n");
377 return;
380 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
381 ok(hr == S_OK, "got 0x%08x\n", hr);
383 hr = pMFCreateSourceResolver(NULL);
384 ok(hr == E_POINTER, "got %#x\n", hr);
386 hr = pMFCreateSourceResolver(&resolver);
387 ok(hr == S_OK, "got %#x\n", hr);
389 hr = pMFCreateSourceResolver(&resolver2);
390 ok(hr == S_OK, "got %#x\n", hr);
391 ok(resolver != resolver2, "Expected new instance\n");
393 IMFSourceResolver_Release(resolver2);
395 filename = load_resource(mp4file);
397 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
398 ok(hr == S_OK, "got 0x%08x\n", hr);
400 hr = IMFSourceResolver_CreateObjectFromByteStream(
401 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
402 &obj_type, (IUnknown **)&mediasource);
403 ok(hr == E_POINTER, "got 0x%08x\n", hr);
405 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
406 NULL, (IUnknown **)&mediasource);
407 ok(hr == E_POINTER, "got 0x%08x\n", hr);
409 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
410 &obj_type, NULL);
411 ok(hr == E_POINTER, "got 0x%08x\n", hr);
413 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
414 &obj_type, (IUnknown **)&mediasource);
415 todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
416 if (hr == S_OK) IMFMediaSource_Release(mediasource);
418 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_BYTESTREAM, NULL,
419 &obj_type, (IUnknown **)&mediasource);
420 todo_wine ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got 0x%08x\n", hr);
422 IMFByteStream_Release(stream);
424 /* We have to create a new bytestream here, because all following
425 * calls to CreateObjectFromByteStream will fail. */
426 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
427 ok(hr == S_OK, "got 0x%08x\n", hr);
429 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
430 ok(hr == S_OK, "got 0x%08x\n", hr);
431 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, file_type);
432 ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr);
433 IMFAttributes_Release(attributes);
435 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
436 &obj_type, (IUnknown **)&mediasource);
437 ok(hr == S_OK, "got 0x%08x\n", hr);
438 ok(mediasource != NULL, "got %p\n", mediasource);
439 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
441 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
442 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
443 ok(descriptor != NULL, "got %p\n", descriptor);
445 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
446 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
448 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
449 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
451 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
452 todo_wine
453 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
455 IMFMediaTypeHandler_Release(handler);
456 IMFStreamDescriptor_Release(sd);
458 IMFPresentationDescriptor_Release(descriptor);
459 IMFMediaSource_Release(mediasource);
460 IMFByteStream_Release(stream);
462 /* Create from URL. */
463 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
465 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
466 (IUnknown **)&stream);
467 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
468 IMFByteStream_Release(stream);
470 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
471 &cancel_cookie, &callback.IMFAsyncCallback_iface, (IUnknown *)resolver);
472 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
473 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
474 IUnknown_Release(cancel_cookie);
476 if (SUCCEEDED(hr))
477 WaitForSingleObject(callback.event, INFINITE);
479 /* With explicit scheme. */
480 lstrcpyW(pathW, fileschemeW);
481 lstrcatW(pathW, filename);
483 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
484 (IUnknown **)&stream);
485 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
486 IMFByteStream_Release(stream);
488 IMFSourceResolver_Release(resolver);
490 /* Create directly through scheme handler. */
491 hr = CoInitialize(NULL);
492 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
493 do_uninit = hr == S_OK;
495 hr = CoCreateInstance(&CLSID_FileSchemeHandler, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
496 (void **)&scheme_handler);
497 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
499 callback2.event = callback.event;
500 cancel_cookie = NULL;
501 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
502 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
503 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
504 ok(!!cancel_cookie, "Unexpected cancel object.\n");
505 IUnknown_Release(cancel_cookie);
507 WaitForSingleObject(callback2.event, INFINITE);
509 IMFSchemeHandler_Release(scheme_handler);
511 if (do_uninit)
512 CoUninitialize();
514 hr = MFShutdown();
515 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
517 DeleteFileW(filename);
519 CloseHandle(callback.event);
522 static void init_functions(void)
524 HMODULE mod = GetModuleHandleA("mfplat.dll");
526 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
527 X(MFAddPeriodicCallback);
528 X(MFAllocateSerialWorkQueue);
529 X(MFCopyImage);
530 X(MFCreateDXGIDeviceManager);
531 X(MFCreateSourceResolver);
532 X(MFCreateMFByteStreamOnStream);
533 X(MFHeapAlloc);
534 X(MFHeapFree);
535 X(MFPutWaitingWorkItem);
536 X(MFRegisterLocalByteStreamHandler);
537 X(MFRegisterLocalSchemeHandler);
538 X(MFRemovePeriodicCallback);
539 X(MFCreateTransformActivate);
540 X(MFTRegisterLocal);
541 X(MFTRegisterLocalByCLSID);
542 X(MFTUnregisterLocal);
543 X(MFTUnregisterLocalByCLSID);
544 #undef X
546 if ((mod = LoadLibraryA("d3d11.dll")))
548 pD3D11CreateDevice = (void *)GetProcAddress(mod, "D3D11CreateDevice");
551 is_win8_plus = pMFPutWaitingWorkItem != NULL;
554 static void test_media_type(void)
556 IMFMediaType *mediatype, *mediatype2;
557 BOOL compressed;
558 DWORD flags;
559 HRESULT hr;
560 GUID guid;
562 if(0)
564 /* Crash on Windows Vista/7 */
565 hr = MFCreateMediaType(NULL);
566 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
569 hr = MFCreateMediaType(&mediatype);
570 ok(hr == S_OK, "got 0x%08x\n", hr);
572 hr = IMFMediaType_GetMajorType(mediatype, &guid);
573 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
575 compressed = FALSE;
576 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
577 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
578 ok(compressed, "Unexpected value %d.\n", compressed);
580 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
581 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
583 compressed = FALSE;
584 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
585 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
586 ok(compressed, "Unexpected value %d.\n", compressed);
588 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
589 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
591 compressed = TRUE;
592 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
593 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
594 ok(!compressed, "Unexpected value %d.\n", compressed);
596 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
597 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
599 hr = IMFMediaType_GetMajorType(mediatype, &guid);
600 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
601 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
603 /* IsEqual() */
604 hr = MFCreateMediaType(&mediatype2);
605 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
607 flags = 0xdeadbeef;
608 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
609 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
610 ok(flags == 0, "Unexpected flags %#x.\n", flags);
612 /* Different major types. */
613 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
614 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
616 flags = 0;
617 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
618 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
619 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
620 "Unexpected flags %#x.\n", flags);
622 /* Same major types, different subtypes. */
623 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
624 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
626 flags = 0;
627 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
628 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
629 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
630 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
632 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
633 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
635 flags = 0;
636 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
637 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
638 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
639 "Unexpected flags %#x.\n", flags);
641 IMFMediaType_Release(mediatype2);
642 IMFMediaType_Release(mediatype);
645 static void test_MFCreateMediaEvent(void)
647 HRESULT hr;
648 IMFMediaEvent *mediaevent;
650 MediaEventType type;
651 GUID extended_type;
652 HRESULT status;
653 PROPVARIANT value;
655 PropVariantInit(&value);
656 value.vt = VT_UNKNOWN;
658 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
659 ok(hr == S_OK, "got 0x%08x\n", hr);
661 PropVariantClear(&value);
663 hr = IMFMediaEvent_GetType(mediaevent, &type);
664 ok(hr == S_OK, "got 0x%08x\n", hr);
665 ok(type == MEError, "got %#x\n", type);
667 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
668 ok(hr == S_OK, "got 0x%08x\n", hr);
669 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
670 wine_dbgstr_guid(&extended_type));
672 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
673 ok(hr == S_OK, "got 0x%08x\n", hr);
674 ok(status == E_FAIL, "got 0x%08x\n", status);
676 PropVariantInit(&value);
677 hr = IMFMediaEvent_GetValue(mediaevent, &value);
678 ok(hr == S_OK, "got 0x%08x\n", hr);
679 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
680 PropVariantClear(&value);
682 IMFMediaEvent_Release(mediaevent);
684 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
685 ok(hr == S_OK, "got 0x%08x\n", hr);
687 hr = IMFMediaEvent_GetType(mediaevent, &type);
688 ok(hr == S_OK, "got 0x%08x\n", hr);
689 ok(type == MEUnknown, "got %#x\n", type);
691 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
692 ok(hr == S_OK, "got 0x%08x\n", hr);
693 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
694 wine_dbgstr_guid(&extended_type));
696 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
697 ok(hr == S_OK, "got 0x%08x\n", hr);
698 ok(status == S_OK, "got 0x%08x\n", status);
700 PropVariantInit(&value);
701 hr = IMFMediaEvent_GetValue(mediaevent, &value);
702 ok(hr == S_OK, "got 0x%08x\n", hr);
703 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
704 PropVariantClear(&value);
706 IMFMediaEvent_Release(mediaevent);
709 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
710 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
712 UINT32 count = expected + 1;
713 HRESULT hr = IMFAttributes_GetCount(obj, &count);
714 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
715 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
718 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
719 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
721 MF_ATTRIBUTE_TYPE type;
722 HRESULT hr;
724 hr = IMFAttributes_GetItemType(obj, key, &type);
725 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
726 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
729 static void test_attributes(void)
731 static const WCHAR stringW[] = {'W','i','n','e',0};
732 static const UINT8 blob[] = {0,1,2,3,4,5};
733 IMFAttributes *attributes, *attributes1;
734 UINT8 blob_value[256], *blob_buf = NULL;
735 MF_ATTRIBUTES_MATCH_TYPE match_type;
736 UINT32 value, string_length, size;
737 PROPVARIANT propvar, ret_propvar;
738 MF_ATTRIBUTE_TYPE type;
739 double double_value;
740 IUnknown *unk_value;
741 WCHAR bufferW[256];
742 UINT64 value64;
743 WCHAR *string;
744 BOOL result;
745 HRESULT hr;
746 GUID key;
748 hr = MFCreateAttributes( &attributes, 3 );
749 ok(hr == S_OK, "got 0x%08x\n", hr);
751 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
752 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
754 CHECK_ATTR_COUNT(attributes, 0);
755 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
756 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
757 CHECK_ATTR_COUNT(attributes, 1);
758 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
760 value = 0xdeadbeef;
761 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
762 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
763 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
765 value64 = 0xdeadbeef;
766 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
767 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
768 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
770 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
771 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
772 CHECK_ATTR_COUNT(attributes, 1);
773 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
775 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
776 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
777 ok(value64 == 65536, "Unexpected value.\n");
779 value = 0xdeadbeef;
780 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
781 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
782 ok(value == 0xdeadbeef, "Unexpected value.\n");
784 IMFAttributes_Release(attributes);
786 hr = MFCreateAttributes(&attributes, 0);
787 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
789 PropVariantInit(&propvar);
790 propvar.vt = MF_ATTRIBUTE_UINT32;
791 U(propvar).ulVal = 123;
792 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
793 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
794 PropVariantInit(&ret_propvar);
795 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
796 U(ret_propvar).ulVal = 0xdeadbeef;
797 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
798 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
799 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
800 PropVariantClear(&ret_propvar);
801 CHECK_ATTR_COUNT(attributes, 1);
803 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
804 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
806 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
807 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
809 PropVariantInit(&ret_propvar);
810 ret_propvar.vt = MF_ATTRIBUTE_STRING;
811 U(ret_propvar).pwszVal = NULL;
812 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
813 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
814 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
815 PropVariantClear(&ret_propvar);
817 PropVariantClear(&propvar);
819 PropVariantInit(&propvar);
820 propvar.vt = MF_ATTRIBUTE_UINT64;
821 U(propvar).uhVal.QuadPart = 65536;
822 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
823 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
824 PropVariantInit(&ret_propvar);
825 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
826 U(ret_propvar).ulVal = 0xdeadbeef;
827 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
828 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
829 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
830 PropVariantClear(&ret_propvar);
831 PropVariantClear(&propvar);
832 CHECK_ATTR_COUNT(attributes, 1);
834 PropVariantInit(&propvar);
835 propvar.vt = VT_I4;
836 U(propvar).lVal = 123;
837 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
838 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
839 PropVariantInit(&ret_propvar);
840 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
841 U(ret_propvar).lVal = 0xdeadbeef;
842 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
843 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
844 PropVariantClear(&propvar);
845 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
846 PropVariantClear(&ret_propvar);
848 PropVariantInit(&propvar);
849 propvar.vt = MF_ATTRIBUTE_UINT32;
850 U(propvar).ulVal = 123;
851 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
852 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
854 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
855 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
856 CHECK_ATTR_COUNT(attributes, 2);
858 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
859 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
860 CHECK_ATTR_COUNT(attributes, 2);
862 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
863 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
864 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
865 PropVariantClear(&ret_propvar);
866 PropVariantClear(&propvar);
868 propvar.vt = MF_ATTRIBUTE_UINT64;
869 U(propvar).uhVal.QuadPart = 65536;
871 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
872 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
873 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
874 PropVariantClear(&ret_propvar);
875 PropVariantClear(&propvar);
877 /* Item ordering is not consistent across Windows version. */
878 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
879 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
880 PropVariantClear(&ret_propvar);
882 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
883 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
884 PropVariantClear(&ret_propvar);
886 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
887 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
888 CHECK_ATTR_COUNT(attributes, 3);
889 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
891 double_value = 0xdeadbeef;
892 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
893 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
894 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
896 propvar.vt = MF_ATTRIBUTE_UINT64;
897 U(propvar).uhVal.QuadPart = 22;
898 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
899 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
900 ok(!result, "Unexpected result.\n");
902 propvar.vt = MF_ATTRIBUTE_DOUBLE;
903 U(propvar).dblVal = 22.0;
904 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
905 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
906 ok(result, "Unexpected result.\n");
908 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
909 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
910 CHECK_ATTR_COUNT(attributes, 3);
911 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
913 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
914 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
915 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
917 string_length = 0xdeadbeef;
918 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
919 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
920 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
921 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
922 CoTaskMemFree(string);
924 string_length = 0xdeadbeef;
925 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
926 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
927 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
928 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
929 memset(bufferW, 0, sizeof(bufferW));
931 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
932 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
933 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
934 memset(bufferW, 0, sizeof(bufferW));
936 string_length = 0;
937 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
938 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
939 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
940 ok(string_length, "Unexpected length.\n");
942 string_length = 0xdeadbeef;
943 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
944 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
945 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
947 /* VT_UNKNOWN */
948 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
949 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
950 CHECK_ATTR_COUNT(attributes, 4);
951 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
953 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
954 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
955 IUnknown_Release(unk_value);
957 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
958 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
959 IUnknown_Release(unk_value);
961 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
962 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
964 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
965 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
966 CHECK_ATTR_COUNT(attributes, 5);
968 unk_value = NULL;
969 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
970 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
972 /* CopyAllItems() */
973 hr = MFCreateAttributes(&attributes1, 0);
974 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
975 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
976 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
977 CHECK_ATTR_COUNT(attributes, 5);
978 CHECK_ATTR_COUNT(attributes1, 5);
980 hr = IMFAttributes_DeleteAllItems(attributes1);
981 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
982 CHECK_ATTR_COUNT(attributes1, 0);
984 propvar.vt = MF_ATTRIBUTE_UINT64;
985 U(propvar).uhVal.QuadPart = 22;
986 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
987 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
988 ok(!result, "Unexpected result.\n");
990 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
991 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
992 CHECK_ATTR_COUNT(attributes, 0);
994 /* Blob */
995 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
996 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
997 CHECK_ATTR_COUNT(attributes, 1);
998 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
999 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1000 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1001 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1003 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1004 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1006 size = 0;
1007 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1008 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1009 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1010 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1012 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1013 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1015 memset(blob_value, 0, sizeof(blob_value));
1016 size = 0;
1017 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1018 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1019 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1020 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1021 CoTaskMemFree(blob_buf);
1023 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1024 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1026 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1027 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1029 IMFAttributes_Release(attributes);
1030 IMFAttributes_Release(attributes1);
1032 /* Compare() */
1033 hr = MFCreateAttributes(&attributes, 0);
1034 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1035 hr = MFCreateAttributes(&attributes1, 0);
1036 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1038 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1039 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1041 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1043 result = FALSE;
1044 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1045 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1046 ok(result, "Unexpected result %d.\n", result);
1048 result = FALSE;
1049 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1050 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1051 ok(result, "Unexpected result %d.\n", result);
1054 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1055 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1057 result = TRUE;
1058 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1059 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1060 ok(!result, "Unexpected result %d.\n", result);
1062 result = TRUE;
1063 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1064 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1065 ok(!result, "Unexpected result %d.\n", result);
1067 result = FALSE;
1068 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1069 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1070 ok(result, "Unexpected result %d.\n", result);
1072 result = FALSE;
1073 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1074 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1075 ok(result, "Unexpected result %d.\n", result);
1077 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1078 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1080 result = TRUE;
1081 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1082 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1083 ok(!result, "Unexpected result %d.\n", result);
1085 result = TRUE;
1086 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1087 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1088 ok(!result, "Unexpected result %d.\n", result);
1090 result = TRUE;
1091 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1092 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1093 ok(!result, "Unexpected result %d.\n", result);
1095 result = TRUE;
1096 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1097 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1098 ok(!result, "Unexpected result %d.\n", result);
1100 result = TRUE;
1101 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1102 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1103 ok(!result, "Unexpected result %d.\n", result);
1105 result = TRUE;
1106 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1107 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1108 ok(!result, "Unexpected result %d.\n", result);
1110 result = TRUE;
1111 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1112 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1113 ok(!result, "Unexpected result %d.\n", result);
1115 result = TRUE;
1116 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1117 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1118 ok(!result, "Unexpected result %d.\n", result);
1120 result = TRUE;
1121 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1122 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1123 ok(!result, "Unexpected result %d.\n", result);
1125 result = TRUE;
1126 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1127 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1128 ok(!result, "Unexpected result %d.\n", result);
1130 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1131 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1133 result = FALSE;
1134 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1135 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1136 ok(result, "Unexpected result %d.\n", result);
1138 result = FALSE;
1139 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1140 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1141 ok(result, "Unexpected result %d.\n", result);
1143 result = FALSE;
1144 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1145 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1146 ok(result, "Unexpected result %d.\n", result);
1148 result = FALSE;
1149 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1150 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1151 ok(result, "Unexpected result %d.\n", result);
1153 result = FALSE;
1154 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1155 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1156 ok(result, "Unexpected result %d.\n", result);
1158 result = FALSE;
1159 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1160 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1161 ok(result, "Unexpected result %d.\n", result);
1163 result = FALSE;
1164 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1165 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1166 ok(result, "Unexpected result %d.\n", result);
1168 result = FALSE;
1169 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1170 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1171 ok(result, "Unexpected result %d.\n", result);
1173 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1174 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1176 result = TRUE;
1177 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1178 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1179 ok(!result, "Unexpected result %d.\n", result);
1181 result = TRUE;
1182 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1183 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1184 ok(!result, "Unexpected result %d.\n", result);
1186 result = FALSE;
1187 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1188 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1189 ok(result, "Unexpected result %d.\n", result);
1191 result = FALSE;
1192 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1193 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1194 ok(result, "Unexpected result %d.\n", result);
1196 result = FALSE;
1197 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1198 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1199 ok(result, "Unexpected result %d.\n", result);
1201 result = TRUE;
1202 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1203 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1204 ok(!result, "Unexpected result %d.\n", result);
1206 result = FALSE;
1207 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1208 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1209 ok(result, "Unexpected result %d.\n", result);
1211 result = TRUE;
1212 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1213 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1214 ok(!result, "Unexpected result %d.\n", result);
1216 result = FALSE;
1217 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1218 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1219 ok(result, "Unexpected result %d.\n", result);
1221 result = FALSE;
1222 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1223 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1224 ok(result, "Unexpected result %d.\n", result);
1226 IMFAttributes_Release(attributes);
1227 IMFAttributes_Release(attributes1);
1230 static void test_MFCreateMFByteStreamOnStream(void)
1232 IMFByteStream *bytestream;
1233 IMFByteStream *bytestream2;
1234 IStream *stream;
1235 IMFAttributes *attributes = NULL;
1236 DWORD caps, written, count;
1237 IUnknown *unknown;
1238 ULONG ref, size;
1239 HRESULT hr;
1241 if(!pMFCreateMFByteStreamOnStream)
1243 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1244 return;
1247 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1248 ok(hr == S_OK, "got 0x%08x\n", hr);
1250 caps = 0xffff0000;
1251 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1252 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1254 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1255 ok(hr == S_OK, "got 0x%08x\n", hr);
1257 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1258 (void **)&unknown);
1259 ok(hr == S_OK, "got 0x%08x\n", hr);
1260 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1261 ref = IUnknown_Release(unknown);
1262 ok(ref == 1, "got %u\n", ref);
1264 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1265 (void **)&bytestream2);
1266 ok(hr == S_OK, "got 0x%08x\n", hr);
1267 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1268 ref = IMFByteStream_Release(bytestream2);
1269 ok(ref == 1, "got %u\n", ref);
1271 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1272 (void **)&attributes);
1273 ok(hr == S_OK ||
1274 /* w7pro64 */
1275 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1277 if (hr != S_OK)
1279 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1280 IStream_Release(stream);
1281 IMFByteStream_Release(bytestream);
1282 return;
1285 ok(attributes != NULL, "got NULL\n");
1286 hr = IMFAttributes_GetCount(attributes, &count);
1287 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1288 ok(count == 0, "Unexpected attributes count %u.\n", count);
1290 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1291 (void **)&unknown);
1292 ok(hr == S_OK, "got 0x%08x\n", hr);
1293 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1294 ref = IUnknown_Release(unknown);
1295 ok(ref == 2, "got %u\n", ref);
1297 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1298 (void **)&bytestream2);
1299 ok(hr == S_OK, "got 0x%08x\n", hr);
1300 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1301 ref = IMFByteStream_Release(bytestream2);
1302 ok(ref == 2, "got %u\n", ref);
1304 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamBuffering, (void **)&unknown);
1305 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1307 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamCacheControl, (void **)&unknown);
1308 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1310 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFMediaEventGenerator, (void **)&unknown);
1311 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1313 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFGetService, (void **)&unknown);
1314 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1316 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1317 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1318 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1320 hr = IMFByteStream_Close(bytestream);
1321 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1323 hr = IMFByteStream_Close(bytestream);
1324 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1326 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1327 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1328 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1330 caps = 0;
1331 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1332 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1333 ok(caps == 0xffff0000, "Unexpected content.\n");
1335 IMFAttributes_Release(attributes);
1336 IMFByteStream_Release(bytestream);
1337 IStream_Release(stream);
1340 static void test_file_stream(void)
1342 IMFByteStream *bytestream, *bytestream2;
1343 QWORD bytestream_length, position;
1344 IMFAttributes *attributes = NULL;
1345 MF_ATTRIBUTE_TYPE item_type;
1346 WCHAR pathW[MAX_PATH];
1347 DWORD caps, count;
1348 WCHAR *filename;
1349 IUnknown *unk;
1350 HRESULT hr;
1351 WCHAR *str;
1352 BOOL eos;
1354 static const WCHAR newfilename[] = {'n','e','w','.','m','p','4',0};
1356 filename = load_resource(mp4file);
1358 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1359 ok(hr == S_OK, "got 0x%08x\n", hr);
1361 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1362 MF_FILEFLAGS_NONE, filename, &bytestream);
1363 ok(hr == S_OK, "got 0x%08x\n", hr);
1365 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamBuffering, (void **)&unk);
1366 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1368 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFByteStreamCacheControl, (void **)&unk);
1369 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1371 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFMediaEventGenerator, (void **)&unk);
1372 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1374 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFGetService, (void **)&unk);
1375 ok(hr == S_OK, "Failed to get interface pointer, hr %#x.\n", hr);
1376 IUnknown_Release(unk);
1378 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1379 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1380 if (is_win8_plus)
1382 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1383 "Unexpected caps %#x.\n", caps);
1385 else
1386 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1388 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1389 (void **)&attributes);
1390 ok(hr == S_OK, "got 0x%08x\n", hr);
1391 ok(attributes != NULL, "got NULL\n");
1393 hr = IMFAttributes_GetCount(attributes, &count);
1394 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1395 ok(count == 2, "Unexpected attributes count %u.\n", count);
1397 /* Original file name. */
1398 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1399 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1400 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1401 CoTaskMemFree(str);
1403 /* Modification time. */
1404 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1405 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1406 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1408 IMFAttributes_Release(attributes);
1410 /* Length. */
1411 hr = IMFByteStream_GetLength(bytestream, NULL);
1412 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1414 bytestream_length = 0;
1415 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1416 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1417 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1419 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1420 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1422 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1423 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1424 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1426 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1427 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1429 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1430 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1432 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1433 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1434 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1436 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1437 MF_FILEFLAGS_NONE, filename, &bytestream2);
1438 ok(hr == S_OK, "got 0x%08x\n", hr);
1439 IMFByteStream_Release(bytestream2);
1441 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1442 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1444 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1445 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1447 IMFByteStream_Release(bytestream);
1449 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1450 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1451 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1453 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1454 MF_FILEFLAGS_NONE, filename, &bytestream);
1455 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1457 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1458 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1459 ok(hr == S_OK, "got 0x%08x\n", hr);
1461 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1462 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1464 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1465 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1467 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1468 newfilename, &bytestream2);
1469 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1471 IMFByteStream_Release(bytestream);
1473 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1474 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1475 ok(hr == S_OK, "got 0x%08x\n", hr);
1477 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1478 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1479 newfilename, &bytestream2);
1480 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1482 IMFByteStream_Release(bytestream);
1484 /* Explicit file: scheme */
1485 lstrcpyW(pathW, fileschemeW);
1486 lstrcatW(pathW, filename);
1487 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
1488 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1490 hr = MFShutdown();
1491 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1493 DeleteFileW(filename);
1494 DeleteFileW(newfilename);
1497 static void test_system_memory_buffer(void)
1499 IMFMediaBuffer *buffer;
1500 HRESULT hr;
1501 DWORD length, max;
1502 BYTE *data, *data2;
1504 hr = MFCreateMemoryBuffer(1024, NULL);
1505 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1507 hr = MFCreateMemoryBuffer(0, &buffer);
1508 ok(hr == S_OK, "got 0x%08x\n", hr);
1509 if(buffer)
1511 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1512 ok(hr == S_OK, "got 0x%08x\n", hr);
1513 ok(length == 0, "got %u\n", length);
1515 IMFMediaBuffer_Release(buffer);
1518 hr = MFCreateMemoryBuffer(1024, &buffer);
1519 ok(hr == S_OK, "got 0x%08x\n", hr);
1521 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
1522 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1524 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1525 ok(hr == S_OK, "got 0x%08x\n", hr);
1526 ok(length == 1024, "got %u\n", length);
1528 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
1529 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1531 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1532 ok(hr == S_OK, "got 0x%08x\n", hr);
1534 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
1535 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1537 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1538 ok(hr == S_OK, "got 0x%08x\n", hr);
1539 ok(length == 10, "got %u\n", length);
1541 length = 0;
1542 max = 0;
1543 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
1544 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1545 ok(length == 0, "got %u\n", length);
1546 ok(max == 0, "got %u\n", length);
1548 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1549 ok(hr == S_OK, "got 0x%08x\n", hr);
1550 ok(length == 10, "got %u\n", length);
1551 ok(max == 1024, "got %u\n", max);
1553 /* Attempt to lock the buffer twice */
1554 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
1555 ok(hr == S_OK, "got 0x%08x\n", hr);
1556 ok(data == data2, "got 0x%08x\n", hr);
1558 hr = IMFMediaBuffer_Unlock(buffer);
1559 ok(hr == S_OK, "got 0x%08x\n", hr);
1561 hr = IMFMediaBuffer_Unlock(buffer);
1562 ok(hr == S_OK, "got 0x%08x\n", hr);
1564 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1565 ok(hr == S_OK, "got 0x%08x\n", hr);
1567 hr = IMFMediaBuffer_Unlock(buffer);
1568 ok(hr == S_OK, "got 0x%08x\n", hr);
1570 /* Extra Unlock */
1571 hr = IMFMediaBuffer_Unlock(buffer);
1572 ok(hr == S_OK, "got 0x%08x\n", hr);
1574 IMFMediaBuffer_Release(buffer);
1576 /* Aligned buffer. */
1577 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
1578 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
1580 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1581 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1582 ok(length == 0, "Unexpected current length %u.\n", length);
1584 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
1585 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1586 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1587 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1588 ok(length == 1, "Unexpected current length %u.\n", length);
1590 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1591 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1592 ok(length == 201, "Unexpected max length %u.\n", length);
1594 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
1595 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1596 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1597 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1598 ok(length == 201, "Unexpected max length %u.\n", length);
1599 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1600 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1602 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1603 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
1604 ok(max == 201 && length == 10, "Unexpected length.\n");
1605 hr = IMFMediaBuffer_Unlock(buffer);
1606 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
1608 IMFMediaBuffer_Release(buffer);
1611 static void test_sample(void)
1613 IMFMediaBuffer *buffer, *buffer2;
1614 DWORD count, flags, length;
1615 IMFAttributes *attributes;
1616 IMFSample *sample;
1617 LONGLONG time;
1618 HRESULT hr;
1620 hr = MFCreateSample( &sample );
1621 ok(hr == S_OK, "got 0x%08x\n", hr);
1623 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
1624 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
1626 CHECK_ATTR_COUNT(attributes, 0);
1628 hr = IMFSample_GetBufferCount(sample, NULL);
1629 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1631 hr = IMFSample_GetBufferCount(sample, &count);
1632 ok(hr == S_OK, "got 0x%08x\n", hr);
1633 ok(count == 0, "got %d\n", count);
1635 hr = IMFSample_GetSampleFlags(sample, &flags);
1636 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
1637 ok(!flags, "Unexpected flags %#x.\n", flags);
1639 hr = IMFSample_SetSampleFlags(sample, 0x123);
1640 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
1641 hr = IMFSample_GetSampleFlags(sample, &flags);
1642 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
1643 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
1645 hr = IMFSample_GetSampleTime(sample, &time);
1646 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
1648 hr = IMFSample_GetSampleDuration(sample, &time);
1649 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
1651 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
1652 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1654 hr = IMFSample_RemoveBufferByIndex(sample, 0);
1655 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1657 hr = IMFSample_RemoveAllBuffers(sample);
1658 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
1660 hr = IMFSample_GetTotalLength(sample, &length);
1661 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1662 ok(!length, "Unexpected total length %u.\n", length);
1664 hr = MFCreateMemoryBuffer(16, &buffer);
1665 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
1667 hr = IMFSample_AddBuffer(sample, buffer);
1668 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1670 hr = IMFSample_AddBuffer(sample, buffer);
1671 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1673 hr = IMFSample_GetBufferCount(sample, &count);
1674 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1675 ok(count == 2, "Unexpected buffer count %u.\n", count);
1677 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
1678 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
1679 ok(buffer2 == buffer, "Unexpected object.\n");
1680 IMFMediaBuffer_Release(buffer2);
1682 hr = IMFSample_GetTotalLength(sample, &length);
1683 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1684 ok(!length, "Unexpected total length %u.\n", length);
1686 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
1687 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1689 hr = IMFSample_GetTotalLength(sample, &length);
1690 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1691 ok(length == 4, "Unexpected total length %u.\n", length);
1693 hr = IMFSample_RemoveBufferByIndex(sample, 1);
1694 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
1696 hr = IMFSample_GetTotalLength(sample, &length);
1697 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
1698 ok(length == 2, "Unexpected total length %u.\n", length);
1700 IMFMediaBuffer_Release(buffer);
1702 /* Duration */
1703 hr = IMFSample_SetSampleDuration(sample, 10);
1704 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
1705 CHECK_ATTR_COUNT(attributes, 0);
1706 hr = IMFSample_GetSampleDuration(sample, &time);
1707 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
1708 ok(time == 10, "Unexpected duration.\n");
1710 /* Timestamp */
1711 hr = IMFSample_SetSampleTime(sample, 1);
1712 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
1713 CHECK_ATTR_COUNT(attributes, 0);
1714 hr = IMFSample_GetSampleTime(sample, &time);
1715 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
1716 ok(time == 1, "Unexpected timestamp.\n");
1718 IMFAttributes_Release(attributes);
1719 IMFSample_Release(sample);
1721 /* ConvertToContiguousBuffer() */
1722 hr = MFCreateSample(&sample);
1723 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
1725 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
1726 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
1728 hr = MFCreateMemoryBuffer(16, &buffer);
1729 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1731 hr = IMFSample_AddBuffer(sample, buffer);
1732 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1734 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1735 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1736 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
1737 IMFMediaBuffer_Release(buffer2);
1739 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1740 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1741 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
1742 IMFMediaBuffer_Release(buffer2);
1744 hr = MFCreateMemoryBuffer(16, &buffer2);
1745 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
1747 hr = IMFSample_AddBuffer(sample, buffer2);
1748 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
1749 IMFMediaBuffer_Release(buffer2);
1751 hr = IMFSample_GetBufferCount(sample, &count);
1752 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1753 ok(count == 2, "Unexpected buffer count %u.\n", count);
1755 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
1756 todo_wine
1757 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
1758 if (SUCCEEDED(hr))
1759 IMFMediaBuffer_Release(buffer2);
1761 hr = IMFSample_GetBufferCount(sample, &count);
1762 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
1763 todo_wine
1764 ok(count == 1, "Unexpected buffer count %u.\n", count);
1766 IMFMediaBuffer_Release(buffer);
1768 IMFSample_Release(sample);
1771 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
1773 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
1774 IMFMediaEventQueue *queue;
1775 IUnknown *state, *obj;
1776 HRESULT hr;
1778 ok(result != NULL, "Unexpected result object.\n");
1780 state = IMFAsyncResult_GetStateNoAddRef(result);
1781 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
1783 IMFMediaEvent *event;
1785 if (is_win8_plus)
1787 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
1788 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
1790 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
1791 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
1793 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
1794 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
1796 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
1797 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
1799 IMFMediaEvent_Release(event);
1802 hr = IMFAsyncResult_GetObject(result, &obj);
1803 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1805 IMFMediaEventQueue_Release(queue);
1807 SetEvent(callback->event);
1810 return E_NOTIMPL;
1813 static const IMFAsyncCallbackVtbl testcallbackvtbl =
1815 testcallback_QueryInterface,
1816 testcallback_AddRef,
1817 testcallback_Release,
1818 testcallback_GetParameters,
1819 testcallback_Invoke,
1822 static void init_test_callback(struct test_callback *callback)
1824 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
1825 callback->event = NULL;
1828 static void test_MFCreateAsyncResult(void)
1830 IMFAsyncResult *result, *result2;
1831 struct test_callback callback;
1832 IUnknown *state, *object;
1833 MFASYNCRESULT *data;
1834 ULONG refcount;
1835 HANDLE event;
1836 DWORD flags;
1837 HRESULT hr;
1838 BOOL ret;
1840 init_test_callback(&callback);
1842 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
1843 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1845 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
1846 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
1848 data = (MFASYNCRESULT *)result;
1849 ok(data->pCallback == NULL, "Unexpected callback value.\n");
1850 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
1851 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
1852 ok(data->hEvent == NULL, "Unexpected event.\n");
1854 hr = IMFAsyncResult_GetState(result, NULL);
1855 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1857 state = (void *)0xdeadbeef;
1858 hr = IMFAsyncResult_GetState(result, &state);
1859 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1860 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
1862 hr = IMFAsyncResult_GetStatus(result);
1863 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
1865 data->hrStatusResult = 123;
1866 hr = IMFAsyncResult_GetStatus(result);
1867 ok(hr == 123, "Unexpected status %#x.\n", hr);
1869 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
1870 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
1871 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
1873 hr = IMFAsyncResult_GetObject(result, NULL);
1874 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
1876 object = (void *)0xdeadbeef;
1877 hr = IMFAsyncResult_GetObject(result, &object);
1878 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
1879 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
1881 state = IMFAsyncResult_GetStateNoAddRef(result);
1882 ok(state == NULL, "Unexpected state.\n");
1884 /* Object. */
1885 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
1886 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
1888 data = (MFASYNCRESULT *)result2;
1889 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
1890 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
1891 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
1892 ok(data->hEvent == NULL, "Unexpected event.\n");
1894 object = NULL;
1895 hr = IMFAsyncResult_GetObject(result2, &object);
1896 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
1897 ok(object == (IUnknown *)result, "Unexpected object.\n");
1898 IUnknown_Release(object);
1900 IMFAsyncResult_Release(result2);
1902 /* State object. */
1903 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
1904 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
1906 data = (MFASYNCRESULT *)result2;
1907 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
1908 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
1909 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
1910 ok(data->hEvent == NULL, "Unexpected event.\n");
1912 state = NULL;
1913 hr = IMFAsyncResult_GetState(result2, &state);
1914 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
1915 ok(state == (IUnknown *)result, "Unexpected state.\n");
1916 IUnknown_Release(state);
1918 state = IMFAsyncResult_GetStateNoAddRef(result2);
1919 ok(state == (IUnknown *)result, "Unexpected state.\n");
1921 refcount = IMFAsyncResult_Release(result2);
1922 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1923 refcount = IMFAsyncResult_Release(result);
1924 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1926 /* Event handle is closed on release. */
1927 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
1928 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
1930 data = (MFASYNCRESULT *)result;
1931 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
1932 ok(data->hEvent != NULL, "Failed to create event.\n");
1933 ret = GetHandleInformation(event, &flags);
1934 ok(ret, "Failed to get handle info.\n");
1936 refcount = IMFAsyncResult_Release(result);
1937 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1938 ret = GetHandleInformation(event, &flags);
1939 ok(!ret, "Expected handle to be closed.\n");
1941 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
1942 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
1944 data = (MFASYNCRESULT *)result;
1945 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
1946 ok(data->hEvent != NULL, "Failed to create event.\n");
1947 ret = GetHandleInformation(event, &flags);
1948 ok(ret, "Failed to get handle info.\n");
1950 refcount = IMFAsyncResult_Release(result);
1951 ok(!refcount, "Unexpected refcount %u.\n", refcount);
1952 ret = GetHandleInformation(event, &flags);
1953 ok(!ret, "Expected handle to be closed.\n");
1956 static void test_startup(void)
1958 DWORD queue;
1959 HRESULT hr;
1961 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
1962 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
1964 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1965 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1967 hr = MFAllocateWorkQueue(&queue);
1968 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
1969 hr = MFUnlockWorkQueue(queue);
1970 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
1972 hr = MFShutdown();
1973 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1975 hr = MFAllocateWorkQueue(&queue);
1976 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
1978 /* Already shut down, has no effect. */
1979 hr = MFShutdown();
1980 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1982 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1983 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1985 hr = MFAllocateWorkQueue(&queue);
1986 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
1987 hr = MFUnlockWorkQueue(queue);
1988 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
1990 hr = MFShutdown();
1991 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1993 /* Platform lock. */
1994 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1995 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
1997 hr = MFAllocateWorkQueue(&queue);
1998 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
1999 hr = MFUnlockWorkQueue(queue);
2000 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2002 /* Unlocking implies shutdown. */
2003 hr = MFUnlockPlatform();
2004 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2006 hr = MFAllocateWorkQueue(&queue);
2007 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2009 hr = MFLockPlatform();
2010 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2012 hr = MFAllocateWorkQueue(&queue);
2013 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2014 hr = MFUnlockWorkQueue(queue);
2015 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2017 hr = MFShutdown();
2018 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2021 static void test_allocate_queue(void)
2023 DWORD queue, queue2;
2024 HRESULT hr;
2026 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2027 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2029 hr = MFAllocateWorkQueue(&queue);
2030 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2031 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2033 hr = MFUnlockWorkQueue(queue);
2034 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2036 hr = MFUnlockWorkQueue(queue);
2037 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2039 hr = MFAllocateWorkQueue(&queue2);
2040 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2041 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2043 hr = MFUnlockWorkQueue(queue2);
2044 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2046 /* Unlock in system queue range. */
2047 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2048 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2050 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2051 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2053 hr = MFUnlockWorkQueue(0x20);
2054 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2056 hr = MFShutdown();
2057 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2060 static void test_MFCopyImage(void)
2062 BYTE dest[16], src[16];
2063 HRESULT hr;
2065 if (!pMFCopyImage)
2067 win_skip("MFCopyImage() is not available.\n");
2068 return;
2071 memset(dest, 0xaa, sizeof(dest));
2072 memset(src, 0x11, sizeof(src));
2074 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2075 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2076 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2078 memset(dest, 0xaa, sizeof(dest));
2079 memset(src, 0x11, sizeof(src));
2081 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2082 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2083 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2085 memset(dest, 0xaa, sizeof(dest));
2086 memset(src, 0x11, sizeof(src));
2088 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2089 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2090 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2093 static void test_MFCreateCollection(void)
2095 IMFCollection *collection;
2096 IUnknown *element;
2097 DWORD count;
2098 HRESULT hr;
2100 hr = MFCreateCollection(NULL);
2101 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2103 hr = MFCreateCollection(&collection);
2104 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2106 hr = IMFCollection_GetElementCount(collection, NULL);
2107 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2109 count = 1;
2110 hr = IMFCollection_GetElementCount(collection, &count);
2111 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2112 ok(count == 0, "Unexpected count %u.\n", count);
2114 hr = IMFCollection_GetElement(collection, 0, NULL);
2115 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2117 element = (void *)0xdeadbeef;
2118 hr = IMFCollection_GetElement(collection, 0, &element);
2119 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2120 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2122 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2123 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2125 element = (void *)0xdeadbeef;
2126 hr = IMFCollection_RemoveElement(collection, 0, &element);
2127 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2128 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2130 hr = IMFCollection_RemoveAllElements(collection);
2131 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2133 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2134 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2136 count = 0;
2137 hr = IMFCollection_GetElementCount(collection, &count);
2138 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2139 ok(count == 1, "Unexpected count %u.\n", count);
2141 hr = IMFCollection_AddElement(collection, NULL);
2142 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2144 count = 0;
2145 hr = IMFCollection_GetElementCount(collection, &count);
2146 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2147 ok(count == 2, "Unexpected count %u.\n", count);
2149 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2150 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2152 count = 0;
2153 hr = IMFCollection_GetElementCount(collection, &count);
2154 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2155 ok(count == 11, "Unexpected count %u.\n", count);
2157 hr = IMFCollection_GetElement(collection, 0, &element);
2158 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2159 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2160 IUnknown_Release(element);
2162 hr = IMFCollection_GetElement(collection, 1, &element);
2163 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2164 ok(!element, "Unexpected element.\n");
2166 hr = IMFCollection_GetElement(collection, 2, &element);
2167 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2168 ok(!element, "Unexpected element.\n");
2170 hr = IMFCollection_GetElement(collection, 10, &element);
2171 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2172 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2173 IUnknown_Release(element);
2175 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2176 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2178 hr = IMFCollection_GetElement(collection, 0, &element);
2179 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2181 hr = IMFCollection_RemoveAllElements(collection);
2182 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2184 count = 1;
2185 hr = IMFCollection_GetElementCount(collection, &count);
2186 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2187 ok(count == 0, "Unexpected count %u.\n", count);
2189 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2190 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2192 IMFCollection_Release(collection);
2195 static void test_MFHeapAlloc(void)
2197 void *res;
2199 if (!pMFHeapAlloc)
2201 win_skip("MFHeapAlloc() is not available.\n");
2202 return;
2205 res = pMFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2206 ok(res != NULL, "MFHeapAlloc failed.\n");
2208 pMFHeapFree(res);
2211 static void test_scheduled_items(void)
2213 struct test_callback callback;
2214 IMFAsyncResult *result;
2215 MFWORKITEM_KEY key, key2;
2216 HRESULT hr;
2218 init_test_callback(&callback);
2220 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2221 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2223 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2224 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2226 hr = MFCancelWorkItem(key);
2227 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2229 hr = MFCancelWorkItem(key);
2230 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2232 if (!pMFPutWaitingWorkItem)
2234 win_skip("Waiting items are not supported.\n");
2235 return;
2238 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2239 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2241 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2242 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2244 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2245 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2247 hr = MFCancelWorkItem(key);
2248 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2250 hr = MFCancelWorkItem(key2);
2251 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2253 IMFAsyncResult_Release(result);
2255 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2256 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2258 hr = MFCancelWorkItem(key);
2259 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2261 hr = MFShutdown();
2262 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2265 static void test_serial_queue(void)
2267 static const DWORD queue_ids[] =
2269 MFASYNC_CALLBACK_QUEUE_STANDARD,
2270 MFASYNC_CALLBACK_QUEUE_RT,
2271 MFASYNC_CALLBACK_QUEUE_IO,
2272 MFASYNC_CALLBACK_QUEUE_TIMER,
2273 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2274 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2276 DWORD queue, serial_queue;
2277 unsigned int i;
2278 HRESULT hr;
2280 if (!pMFAllocateSerialWorkQueue)
2282 win_skip("Serial queues are not supported.\n");
2283 return;
2286 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2287 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2289 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2291 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2292 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2294 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2295 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2296 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2298 if (SUCCEEDED(hr))
2300 hr = MFUnlockWorkQueue(serial_queue);
2301 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2305 /* Chain them together. */
2306 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2307 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2309 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2310 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2312 hr = MFUnlockWorkQueue(serial_queue);
2313 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2315 hr = MFUnlockWorkQueue(queue);
2316 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2318 hr = MFShutdown();
2319 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2322 static LONG periodic_counter;
2323 static void CALLBACK periodic_callback(IUnknown *context)
2325 InterlockedIncrement(&periodic_counter);
2328 static void test_periodic_callback(void)
2330 DWORD period, key;
2331 HRESULT hr;
2333 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2334 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2336 period = 0;
2337 hr = MFGetTimerPeriodicity(&period);
2338 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2339 ok(period == 10, "Unexpected period %u.\n", period);
2341 if (!pMFAddPeriodicCallback)
2343 win_skip("Periodic callbacks are not supported.\n");
2344 hr = MFShutdown();
2345 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2346 return;
2349 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2351 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2352 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2353 ok(key != 0, "Unexpected key %#x.\n", key);
2355 Sleep(10 * period);
2357 hr = pMFRemovePeriodicCallback(key);
2358 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2360 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2362 hr = MFShutdown();
2363 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2366 static void test_event_queue(void)
2368 struct test_callback callback, callback2;
2369 IMFMediaEvent *event, *event2;
2370 IMFMediaEventQueue *queue;
2371 IMFAsyncResult *result;
2372 HRESULT hr;
2373 DWORD ret;
2375 init_test_callback(&callback);
2376 init_test_callback(&callback2);
2378 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2379 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2381 hr = MFCreateEventQueue(&queue);
2382 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
2384 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2385 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2387 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2388 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2390 if (is_win8_plus)
2392 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2393 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2395 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
2396 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2397 ok(event2 == event, "Unexpected event object.\n");
2398 IMFMediaEvent_Release(event2);
2400 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2401 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2403 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
2404 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2405 IMFMediaEvent_Release(event2);
2408 /* Async case. */
2409 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2410 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2412 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2413 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
2415 /* Same callback, same state. */
2416 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2417 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2419 /* Same callback, different state. */
2420 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
2421 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2423 /* Different callback, same state. */
2424 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
2425 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2427 /* Different callback, different state. */
2428 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
2429 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2431 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
2433 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2434 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2436 ret = WaitForSingleObject(callback.event, 100);
2437 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
2439 CloseHandle(callback.event);
2441 IMFMediaEvent_Release(event);
2443 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2444 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2446 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2447 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
2449 /* Shutdown behavior. */
2450 hr = IMFMediaEventQueue_Shutdown(queue);
2451 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2453 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2454 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2456 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2457 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2458 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2459 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2460 IMFMediaEvent_Release(event);
2462 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2463 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2465 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2466 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2468 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
2469 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2471 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2472 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2474 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2475 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2476 IMFAsyncResult_Release(result);
2478 /* Already shut down. */
2479 hr = IMFMediaEventQueue_Shutdown(queue);
2480 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2482 IMFMediaEventQueue_Release(queue);
2484 hr = MFShutdown();
2485 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2488 static void test_presentation_descriptor(void)
2490 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
2491 IMFPresentationDescriptor *pd, *pd2;
2492 IMFMediaType *media_type;
2493 unsigned int i;
2494 BOOL selected;
2495 UINT64 value;
2496 DWORD count;
2497 HRESULT hr;
2499 hr = MFCreateMediaType(&media_type);
2500 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2502 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
2504 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
2505 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
2508 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
2509 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
2511 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
2512 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
2514 for (i = 0; i < count; ++i)
2516 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
2517 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2518 ok(!selected, "Unexpected selected state.\n");
2519 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
2520 IMFStreamDescriptor_Release(stream_desc2);
2523 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
2524 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2526 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
2527 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2529 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
2530 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
2532 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
2533 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2534 ok(!!selected, "Unexpected selected state.\n");
2535 IMFStreamDescriptor_Release(stream_desc2);
2537 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
2538 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
2540 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
2541 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
2543 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
2544 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
2545 ok(!!selected, "Unexpected selected state.\n");
2546 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
2547 IMFStreamDescriptor_Release(stream_desc2);
2549 value = 0;
2550 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
2551 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
2552 ok(value == 1, "Unexpected attribute value.\n");
2554 IMFPresentationDescriptor_Release(pd2);
2555 IMFPresentationDescriptor_Release(pd);
2557 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
2559 IMFStreamDescriptor_Release(stream_desc[i]);
2562 /* Partially initialized array. */
2563 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
2564 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
2565 stream_desc[0] = NULL;
2567 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
2568 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2570 IMFStreamDescriptor_Release(stream_desc[1]);
2571 IMFMediaType_Release(media_type);
2574 enum clock_action
2576 CLOCK_START,
2577 CLOCK_STOP,
2578 CLOCK_PAUSE,
2579 CLOCK_RESTART,
2582 static void test_system_time_source(void)
2584 static const struct clock_state_test
2586 enum clock_action action;
2587 MFCLOCK_STATE state;
2588 BOOL is_invalid;
2590 clock_state_change[] =
2592 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
2593 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
2594 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2595 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
2596 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2597 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2598 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
2599 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2600 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2601 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
2602 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2603 { CLOCK_START, MFCLOCK_STATE_RUNNING },
2604 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
2605 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
2606 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
2607 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
2608 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
2610 IMFPresentationTimeSource *time_source, *time_source2;
2611 IMFClockStateSink *statesink;
2612 IMFClock *clock, *clock2;
2613 MFCLOCK_PROPERTIES props;
2614 MFCLOCK_STATE state;
2615 unsigned int i;
2616 MFTIME systime;
2617 LONGLONG time;
2618 DWORD value;
2619 HRESULT hr;
2621 hr = MFCreateSystemTimeSource(&time_source);
2622 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2624 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
2625 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
2626 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
2627 "Unexpected flags %#x.\n", value);
2629 value = 1;
2630 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
2631 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2632 ok(value == 0, "Unexpected value %u.\n", value);
2634 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2635 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
2636 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
2638 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
2639 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
2641 /* State changes. */
2642 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
2644 switch (clock_state_change[i].action)
2646 case CLOCK_STOP:
2647 hr = IMFClockStateSink_OnClockStop(statesink, 0);
2648 break;
2649 case CLOCK_RESTART:
2650 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
2651 break;
2652 case CLOCK_PAUSE:
2653 hr = IMFClockStateSink_OnClockPause(statesink, 0);
2654 break;
2655 case CLOCK_START:
2656 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
2657 break;
2658 default:
2661 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
2662 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2663 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
2664 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
2667 IMFClockStateSink_Release(statesink);
2669 /* Properties. */
2670 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
2671 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2673 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
2674 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
2676 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
2677 wine_dbgstr_longlong(props.qwCorrelationRate));
2678 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
2679 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
2680 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
2681 wine_dbgstr_longlong(props.qwClockFrequency));
2682 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
2683 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
2685 /* Underlying clock. */
2686 hr = MFCreateSystemTimeSource(&time_source2);
2687 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
2688 EXPECT_REF(time_source2, 1);
2689 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
2690 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2691 EXPECT_REF(time_source2, 1);
2692 EXPECT_REF(clock2, 2);
2694 EXPECT_REF(time_source, 1);
2695 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
2696 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2697 EXPECT_REF(time_source, 1);
2698 EXPECT_REF(clock, 2);
2700 ok(clock != clock2, "Unexpected clock instance.\n");
2702 IMFPresentationTimeSource_Release(time_source2);
2703 IMFClock_Release(clock2);
2705 hr = IMFClock_GetClockCharacteristics(clock, &value);
2706 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
2707 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
2708 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
2710 hr = IMFClock_GetContinuityKey(clock, &value);
2711 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
2712 ok(value == 0, "Unexpected key value %u.\n", value);
2714 hr = IMFClock_GetState(clock, 0, &state);
2715 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
2716 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
2718 hr = IMFClock_GetProperties(clock, &props);
2719 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
2721 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
2722 wine_dbgstr_longlong(props.qwCorrelationRate));
2723 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
2724 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
2725 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
2726 wine_dbgstr_longlong(props.qwClockFrequency));
2727 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
2728 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
2730 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
2731 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
2732 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2734 IMFClock_Release(clock);
2736 /* Test returned time regarding specified rate and offset. */
2737 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
2738 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
2740 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
2741 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
2742 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
2744 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2745 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2746 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2748 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
2749 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2751 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2752 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2753 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2755 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
2756 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2758 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2759 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2760 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2761 wine_dbgstr_longlong(systime));
2763 hr = IMFClockStateSink_OnClockPause(statesink, 2);
2764 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2766 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2767 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2768 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2770 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
2771 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
2773 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2774 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2775 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2776 wine_dbgstr_longlong(systime));
2778 hr = IMFClockStateSink_OnClockPause(statesink, 0);
2779 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2781 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2782 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2783 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2784 wine_dbgstr_longlong(systime));
2786 hr = IMFClockStateSink_OnClockStop(statesink, 123);
2787 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
2789 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2790 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2791 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2793 /* Increased rate. */
2794 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
2795 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
2797 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
2798 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2800 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2801 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2802 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2803 wine_dbgstr_longlong(2 * systime));
2805 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
2806 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2808 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2809 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2810 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2811 wine_dbgstr_longlong(2 * systime));
2813 hr = IMFClockStateSink_OnClockPause(statesink, 2);
2814 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2816 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2817 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2818 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2819 wine_dbgstr_longlong(systime));
2821 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
2822 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
2824 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2825 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2826 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2827 wine_dbgstr_longlong(systime));
2829 hr = IMFClockStateSink_OnClockPause(statesink, 0);
2830 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2832 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2833 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2834 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2835 wine_dbgstr_longlong(systime));
2837 hr = IMFClockStateSink_OnClockStop(statesink, 123);
2838 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
2840 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2841 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2842 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
2843 IMFClockStateSink_Release(statesink);
2845 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
2846 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2848 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2849 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2850 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2851 wine_dbgstr_longlong(2 * systime));
2853 hr = IMFClockStateSink_OnClockStop(statesink, 123);
2854 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
2856 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
2857 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
2859 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2860 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2861 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2862 wine_dbgstr_longlong(2 * systime));
2864 hr = IMFClockStateSink_OnClockPause(statesink, 2);
2865 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2867 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2868 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2869 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2870 wine_dbgstr_longlong(systime));
2872 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
2873 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
2875 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2876 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2877 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2878 wine_dbgstr_longlong(systime));
2880 hr = IMFClockStateSink_OnClockPause(statesink, 0);
2881 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
2883 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
2884 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
2885 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
2886 wine_dbgstr_longlong(systime));
2888 IMFPresentationTimeSource_Release(time_source);
2891 static void test_MFInvokeCallback(void)
2893 struct test_callback callback;
2894 IMFAsyncResult *result;
2895 MFASYNCRESULT *data;
2896 ULONG refcount;
2897 HRESULT hr;
2898 DWORD ret;
2900 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2901 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2903 init_test_callback(&callback);
2905 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2906 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2908 data = (MFASYNCRESULT *)result;
2909 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
2910 ok(data->hEvent != NULL, "Failed to create event.\n");
2912 hr = MFInvokeCallback(result);
2913 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
2915 ret = WaitForSingleObject(data->hEvent, 100);
2916 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
2918 refcount = IMFAsyncResult_Release(result);
2919 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2921 hr = MFShutdown();
2922 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2925 static void test_stream_descriptor(void)
2927 IMFMediaType *media_types[2], *media_type;
2928 IMFMediaTypeHandler *type_handler;
2929 IMFStreamDescriptor *stream_desc;
2930 GUID major_type;
2931 DWORD id, count;
2932 unsigned int i;
2933 HRESULT hr;
2935 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
2936 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2938 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
2940 hr = MFCreateMediaType(&media_types[i]);
2941 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2944 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
2945 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2947 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
2948 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2950 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
2951 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
2952 ok(id == 123, "Unexpected id %#x.\n", id);
2954 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
2955 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
2957 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
2958 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
2959 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
2961 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
2962 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
2964 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
2965 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
2967 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
2969 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
2970 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
2971 ok(media_type == media_types[i], "Unexpected object.\n");
2973 if (SUCCEEDED(hr))
2974 IMFMediaType_Release(media_type);
2977 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
2978 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
2980 hr = MFCreateMediaType(&media_type);
2981 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2983 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
2984 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
2986 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
2987 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
2989 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
2990 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
2992 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
2993 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
2994 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
2996 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
2997 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
2998 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3000 IMFMediaType_Release(media_type);
3002 IMFMediaTypeHandler_Release(type_handler);
3004 IMFStreamDescriptor_Release(stream_desc);
3007 static void test_MFCalculateImageSize(void)
3009 static const struct image_size_test
3011 const GUID *subtype;
3012 UINT32 width;
3013 UINT32 height;
3014 UINT32 size;
3016 image_size_tests[] =
3018 { &MFVideoFormat_RGB8, 3, 5, 20 },
3019 { &MFVideoFormat_RGB8, 1, 1, 4 },
3020 { &MFVideoFormat_RGB555, 3, 5, 40 },
3021 { &MFVideoFormat_RGB555, 1, 1, 4 },
3022 { &MFVideoFormat_RGB565, 3, 5, 40 },
3023 { &MFVideoFormat_RGB565, 1, 1, 4 },
3024 { &MFVideoFormat_RGB24, 3, 5, 60 },
3025 { &MFVideoFormat_RGB24, 1, 1, 4 },
3026 { &MFVideoFormat_RGB32, 3, 5, 60 },
3027 { &MFVideoFormat_RGB32, 1, 1, 4 },
3028 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3029 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3030 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3031 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3032 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3033 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3035 unsigned int i;
3036 UINT32 size;
3037 HRESULT hr;
3039 size = 1;
3040 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
3041 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
3042 ok(size == 0, "Unexpected size %u.\n", size);
3044 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
3046 /* Those are supported since Win10. */
3047 BOOL is_broken = IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A16B16G16R16F) ||
3048 IsEqualGUID(image_size_tests[i].subtype, &MFVideoFormat_A2R10G10B10);
3050 hr = MFCalculateImageSize(image_size_tests[i].subtype, image_size_tests[i].width,
3051 image_size_tests[i].height, &size);
3052 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
3053 ok(size == image_size_tests[i].size, "%u: unexpected image size %u, expected %u.\n", i, size,
3054 image_size_tests[i].size);
3058 static void test_MFCompareFullToPartialMediaType(void)
3060 IMFMediaType *full_type, *partial_type;
3061 HRESULT hr;
3062 BOOL ret;
3064 hr = MFCreateMediaType(&full_type);
3065 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3067 hr = MFCreateMediaType(&partial_type);
3068 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3070 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3071 ok(!ret, "Unexpected result %d.\n", ret);
3073 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3074 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3076 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3077 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3079 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3080 ok(ret, "Unexpected result %d.\n", ret);
3082 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
3083 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3085 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3086 ok(ret, "Unexpected result %d.\n", ret);
3088 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
3089 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3091 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3092 ok(!ret, "Unexpected result %d.\n", ret);
3094 IMFMediaType_Release(full_type);
3095 IMFMediaType_Release(partial_type);
3098 static void test_attributes_serialization(void)
3100 static const WCHAR textW[] = {'T','e','x','t',0};
3101 static const UINT8 blob[] = {1,2,3};
3102 IMFAttributes *attributes, *dest;
3103 UINT32 size, count, value32;
3104 double value_dbl;
3105 UINT64 value64;
3106 UINT8 *buffer;
3107 IUnknown *obj;
3108 HRESULT hr;
3109 WCHAR *str;
3110 GUID guid;
3112 hr = MFCreateAttributes(&attributes, 0);
3113 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3115 hr = MFCreateAttributes(&dest, 0);
3116 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3118 hr = MFGetAttributesAsBlobSize(attributes, &size);
3119 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3120 ok(size == 8, "Got size %u.\n", size);
3122 buffer = heap_alloc(size);
3124 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3125 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3127 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
3128 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
3130 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
3131 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3133 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
3134 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3136 hr = MFInitAttributesFromBlob(dest, buffer, size);
3137 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3139 /* Previous items are cleared. */
3140 hr = IMFAttributes_GetCount(dest, &count);
3141 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3142 ok(count == 0, "Unexpected count %u.\n", count);
3144 heap_free(buffer);
3146 /* Set some attributes of various types. */
3147 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
3148 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
3149 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
3150 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
3151 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
3152 IMFAttributes_SetString(attributes, &DUMMY_CLSID, textW);
3153 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
3155 hr = MFGetAttributesAsBlobSize(attributes, &size);
3156 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3157 ok(size > 8, "Got unexpected size %u.\n", size);
3159 buffer = heap_alloc(size);
3160 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3161 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3162 hr = MFInitAttributesFromBlob(dest, buffer, size);
3163 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3164 heap_free(buffer);
3166 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
3167 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
3168 ok(value32 == 456, "Unexpected value %u.\n", value32);
3169 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
3170 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
3171 ok(value64 == 123, "Unexpected value.\n");
3172 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
3173 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
3174 ok(value_dbl == 0.5, "Unexpected value.\n");
3175 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
3176 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3177 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
3178 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
3179 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
3180 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
3181 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
3182 ok(!lstrcmpW(str, textW), "Unexpected string.\n");
3183 CoTaskMemFree(str);
3184 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
3185 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
3186 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
3187 CoTaskMemFree(buffer);
3189 IMFAttributes_Release(attributes);
3190 IMFAttributes_Release(dest);
3193 static void test_wrapped_media_type(void)
3195 IMFMediaType *mediatype, *mediatype2;
3196 UINT32 count, type;
3197 HRESULT hr;
3198 GUID guid;
3200 hr = MFCreateMediaType(&mediatype);
3201 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3203 hr = MFUnwrapMediaType(mediatype, &mediatype2);
3204 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3206 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
3207 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3208 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
3209 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3211 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3212 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
3214 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
3215 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
3217 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
3218 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3219 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
3221 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
3222 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
3223 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
3225 hr = IMFMediaType_GetCount(mediatype2, &count);
3226 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
3227 ok(count == 3, "Unexpected count %u.\n", count);
3229 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
3230 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
3231 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
3233 IMFMediaType_Release(mediatype);
3235 hr = MFUnwrapMediaType(mediatype2, &mediatype);
3236 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
3238 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
3239 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3240 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
3242 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
3243 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3245 IMFMediaType_Release(mediatype);
3246 IMFMediaType_Release(mediatype2);
3249 static void test_MFCreateWaveFormatExFromMFMediaType(void)
3251 WAVEFORMATEXTENSIBLE *format_ext;
3252 IMFMediaType *mediatype;
3253 WAVEFORMATEX *format;
3254 UINT32 size;
3255 HRESULT hr;
3257 hr = MFCreateMediaType(&mediatype);
3258 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3260 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3261 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3263 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3264 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3266 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3267 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3269 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
3270 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3272 /* Audio/PCM */
3273 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3274 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3275 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3276 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3278 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
3279 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3280 ok(format != NULL, "Expected format structure.\n");
3281 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
3282 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
3283 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
3284 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
3285 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
3286 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
3287 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
3288 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
3289 CoTaskMemFree(format);
3291 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
3292 MFWaveFormatExConvertFlag_ForceExtensible);
3293 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3294 ok(format_ext != NULL, "Expected format structure.\n");
3295 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
3296 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
3297 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
3298 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
3299 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
3300 format_ext->Format.nAvgBytesPerSec);
3301 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
3302 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
3303 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
3304 format_ext->Format.cbSize);
3305 CoTaskMemFree(format_ext);
3307 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
3308 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
3309 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
3310 CoTaskMemFree(format);
3312 IMFMediaType_Release(mediatype);
3315 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
3317 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
3318 IMFByteStream *stream;
3319 IUnknown *object;
3320 HRESULT hr;
3322 ok(!!result, "Unexpected result object.\n");
3324 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
3326 hr = IMFAsyncResult_GetObject(result, &object);
3327 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3329 hr = MFEndCreateFile(result, &stream);
3330 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
3331 IMFByteStream_Release(stream);
3333 SetEvent(callback->event);
3335 return S_OK;
3338 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
3340 testcallback_QueryInterface,
3341 testcallback_AddRef,
3342 testcallback_Release,
3343 testcallback_GetParameters,
3344 test_create_file_callback_Invoke,
3347 static void test_async_create_file(void)
3349 struct test_callback callback = { { &test_create_file_callback_vtbl } };
3350 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
3351 IUnknown *cancel_cookie;
3352 HRESULT hr;
3353 BOOL ret;
3355 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3356 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
3358 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
3360 GetTempPathW(ARRAY_SIZE(pathW), pathW);
3361 GetTempFileNameW(pathW, NULL, 0, fileW);
3363 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
3364 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
3365 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
3366 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
3368 WaitForSingleObject(callback.event, INFINITE);
3370 IUnknown_Release(cancel_cookie);
3372 CloseHandle(callback.event);
3374 hr = MFShutdown();
3375 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3377 ret = DeleteFileW(fileW);
3378 ok(ret, "Failed to delete test file.\n");
3381 struct activate_object
3383 IMFActivate IMFActivate_iface;
3384 LONG refcount;
3387 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
3389 if (IsEqualIID(riid, &IID_IMFActivate) ||
3390 IsEqualIID(riid, &IID_IMFAttributes) ||
3391 IsEqualIID(riid, &IID_IUnknown))
3393 *obj = iface;
3394 IMFActivate_AddRef(iface);
3395 return S_OK;
3398 *obj = NULL;
3399 return E_NOINTERFACE;
3402 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
3404 return 2;
3407 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
3409 return 1;
3412 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
3414 return E_NOTIMPL;
3417 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
3419 return E_NOTIMPL;
3422 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
3424 return E_NOTIMPL;
3427 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
3428 BOOL *result)
3430 return E_NOTIMPL;
3433 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
3435 return E_NOTIMPL;
3438 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
3440 return E_NOTIMPL;
3443 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
3445 return E_NOTIMPL;
3448 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
3450 return E_NOTIMPL;
3453 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
3455 return E_NOTIMPL;
3458 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
3459 UINT32 size, UINT32 *length)
3461 return E_NOTIMPL;
3464 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
3465 WCHAR **value, UINT32 *length)
3467 return E_NOTIMPL;
3470 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
3472 return E_NOTIMPL;
3475 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
3476 UINT32 bufsize, UINT32 *blobsize)
3478 return E_NOTIMPL;
3481 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
3483 return E_NOTIMPL;
3486 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
3488 return E_NOTIMPL;
3491 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
3493 return E_NOTIMPL;
3496 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
3498 return E_NOTIMPL;
3501 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
3503 return E_NOTIMPL;
3506 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
3508 return E_NOTIMPL;
3511 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
3513 return E_NOTIMPL;
3516 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
3518 return E_NOTIMPL;
3521 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
3523 return E_NOTIMPL;
3526 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
3528 return E_NOTIMPL;
3531 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
3533 return E_NOTIMPL;
3536 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
3538 return E_NOTIMPL;
3541 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
3543 return E_NOTIMPL;
3546 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
3548 return E_NOTIMPL;
3551 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
3553 return E_NOTIMPL;
3556 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
3558 return E_NOTIMPL;
3561 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
3563 return E_NOTIMPL;
3566 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
3568 return E_NOTIMPL;
3571 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
3573 return E_NOTIMPL;
3576 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
3578 return E_NOTIMPL;
3581 static const IMFActivateVtbl activate_object_vtbl =
3583 activate_object_QueryInterface,
3584 activate_object_AddRef,
3585 activate_object_Release,
3586 activate_object_GetItem,
3587 activate_object_GetItemType,
3588 activate_object_CompareItem,
3589 activate_object_Compare,
3590 activate_object_GetUINT32,
3591 activate_object_GetUINT64,
3592 activate_object_GetDouble,
3593 activate_object_GetGUID,
3594 activate_object_GetStringLength,
3595 activate_object_GetString,
3596 activate_object_GetAllocatedString,
3597 activate_object_GetBlobSize,
3598 activate_object_GetBlob,
3599 activate_object_GetAllocatedBlob,
3600 activate_object_GetUnknown,
3601 activate_object_SetItem,
3602 activate_object_DeleteItem,
3603 activate_object_DeleteAllItems,
3604 activate_object_SetUINT32,
3605 activate_object_SetUINT64,
3606 activate_object_SetDouble,
3607 activate_object_SetGUID,
3608 activate_object_SetString,
3609 activate_object_SetBlob,
3610 activate_object_SetUnknown,
3611 activate_object_LockStore,
3612 activate_object_UnlockStore,
3613 activate_object_GetCount,
3614 activate_object_GetItemByIndex,
3615 activate_object_CopyAllItems,
3616 activate_object_ActivateObject,
3617 activate_object_ShutdownObject,
3618 activate_object_DetachObject,
3621 static void test_local_handlers(void)
3623 IMFActivate local_activate = { &activate_object_vtbl };
3624 static const WCHAR localW[] = {'l','o','c','a','l',0};
3625 HRESULT hr;
3627 if (!pMFRegisterLocalSchemeHandler)
3629 win_skip("Local handlers are not supported.\n");
3630 return;
3633 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
3634 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3636 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
3637 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3639 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
3640 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3642 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
3643 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
3645 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
3646 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
3648 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
3649 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3651 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
3652 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3654 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
3655 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
3657 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
3658 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
3660 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
3661 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
3664 static void test_create_property_store(void)
3666 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
3667 IPropertyStore *store, *store2;
3668 PROPVARIANT value = {0};
3669 PROPERTYKEY key;
3670 ULONG refcount;
3671 IUnknown *unk;
3672 DWORD count;
3673 HRESULT hr;
3675 hr = CreatePropertyStore(NULL);
3676 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3678 hr = CreatePropertyStore(&store);
3679 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
3681 hr = CreatePropertyStore(&store2);
3682 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
3683 ok(store2 != store, "Expected different store objects.\n");
3684 IPropertyStore_Release(store2);
3686 hr = IPropertyStore_QueryInterface(store, &IID_IPropertyStoreCache, (void **)&unk);
3687 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
3688 hr = IPropertyStore_QueryInterface(store, &IID_IPersistSerializedPropStorage, (void **)&unk);
3689 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
3691 hr = IPropertyStore_GetCount(store, NULL);
3692 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3694 count = 0xdeadbeef;
3695 hr = IPropertyStore_GetCount(store, &count);
3696 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
3697 ok(!count, "Unexpected count %u.\n", count);
3699 hr = IPropertyStore_Commit(store);
3700 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3702 hr = IPropertyStore_GetAt(store, 0, &key);
3703 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3705 hr = IPropertyStore_GetValue(store, NULL, &value);
3706 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
3708 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
3709 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3711 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
3712 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
3714 memset(&value, 0, sizeof(PROPVARIANT));
3715 value.vt = VT_I4;
3716 value.lVal = 0xdeadbeef;
3717 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
3718 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3720 if (0)
3722 /* crashes on Windows */
3723 hr = IPropertyStore_SetValue(store, NULL, &value);
3724 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3727 hr = IPropertyStore_GetCount(store, &count);
3728 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
3729 ok(count == 1, "Unexpected count %u.\n", count);
3731 hr = IPropertyStore_Commit(store);
3732 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
3734 hr = IPropertyStore_GetAt(store, 0, &key);
3735 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3736 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
3738 hr = IPropertyStore_GetAt(store, 1, &key);
3739 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3741 memset(&value, 0xcc, sizeof(PROPVARIANT));
3742 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
3743 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3744 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
3745 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
3747 memset(&value, 0, sizeof(PROPVARIANT));
3748 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
3749 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3751 hr = IPropertyStore_GetCount(store, &count);
3752 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
3753 ok(count == 1, "Unexpected count %u.\n", count);
3755 memset(&value, 0xcc, sizeof(PROPVARIANT));
3756 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
3757 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3758 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
3759 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
3761 refcount = IPropertyStore_Release(store);
3762 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3765 static void test_dxgi_device_manager(void)
3767 IMFDXGIDeviceManager *manager, *manager2;
3768 ID3D11Device *d3d11_dev, *d3d11_dev2;
3769 UINT token, token2;
3770 HRESULT hr;
3772 if (!pMFCreateDXGIDeviceManager)
3774 win_skip("MFCreateDXGIDeviceManager not found.\n");
3775 return;
3778 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
3779 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
3781 token = 0;
3782 hr = pMFCreateDXGIDeviceManager(&token, NULL);
3783 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
3784 ok(!token, "got wrong token: %u.\n", token);
3786 hr = pMFCreateDXGIDeviceManager(&token, &manager);
3787 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
3788 EXPECT_REF(manager, 1);
3789 ok(!!token, "got wrong token: %u.\n", token);
3791 Sleep(50);
3792 token2 = 0;
3793 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
3794 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
3795 EXPECT_REF(manager2, 1);
3796 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
3797 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
3798 EXPECT_REF(manager, 1);
3800 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
3801 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
3802 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
3803 EXPECT_REF(d3d11_dev, 1);
3805 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
3806 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
3807 EXPECT_REF(d3d11_dev, 1);
3809 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
3810 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
3812 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
3813 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
3814 EXPECT_REF(manager, 1);
3815 EXPECT_REF(d3d11_dev, 2);
3817 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
3818 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
3819 EXPECT_REF(manager2, 1);
3820 EXPECT_REF(d3d11_dev, 2);
3822 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
3823 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
3824 EXPECT_REF(manager, 1);
3825 EXPECT_REF(d3d11_dev, 2);
3827 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
3828 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
3829 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
3830 EXPECT_REF(d3d11_dev2, 1);
3831 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
3832 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
3833 EXPECT_REF(manager, 1);
3834 EXPECT_REF(d3d11_dev2, 2);
3835 EXPECT_REF(d3d11_dev, 1);
3837 IMFDXGIDeviceManager_Release(manager);
3838 EXPECT_REF(d3d11_dev2, 1);
3839 ID3D11Device_Release(d3d11_dev);
3840 ID3D11Device_Release(d3d11_dev2);
3841 IMFDXGIDeviceManager_Release(manager2);
3844 static void test_MFCreateTransformActivate(void)
3846 IMFActivate *activate;
3847 UINT32 count;
3848 HRESULT hr;
3850 if (!pMFCreateTransformActivate)
3852 win_skip("MFCreateTransformActivate() is not available.\n");
3853 return;
3856 hr = pMFCreateTransformActivate(&activate);
3857 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
3859 hr = IMFActivate_GetCount(activate, &count);
3860 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
3861 ok(!count, "Unexpected attribute count %u.\n", count);
3863 IMFActivate_Release(activate);
3866 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
3868 if (IsEqualIID(riid, &IID_IClassFactory) ||
3869 IsEqualIID(riid, &IID_IUnknown))
3871 *obj = iface;
3872 IClassFactory_AddRef(iface);
3873 return S_OK;
3876 *obj = NULL;
3877 return E_NOINTERFACE;
3880 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
3882 return 2;
3885 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
3887 return 1;
3890 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
3892 ok(0, "Unexpected call.\n");
3893 return E_NOTIMPL;
3896 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
3898 return S_OK;
3901 static const IClassFactoryVtbl test_mft_factory_vtbl =
3903 test_mft_factory_QueryInterface,
3904 test_mft_factory_AddRef,
3905 test_mft_factory_Release,
3906 test_mft_factory_CreateInstance,
3907 test_mft_factory_LockServer,
3910 static void test_MFTRegisterLocal(void)
3912 IClassFactory test_factory = { &test_mft_factory_vtbl };
3913 MFT_REGISTER_TYPE_INFO input_types[1];
3914 HRESULT hr;
3916 if (!pMFTRegisterLocal)
3918 win_skip("MFTRegisterLocal() is not available.\n");
3919 return;
3922 input_types[0].guidMajorType = MFMediaType_Audio;
3923 input_types[0].guidSubtype = MFAudioFormat_PCM;
3924 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
3925 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
3927 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
3928 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
3930 hr = pMFTUnregisterLocal(&test_factory);
3931 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
3933 hr = pMFTUnregisterLocal(&test_factory);
3934 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
3936 hr = pMFTUnregisterLocal(NULL);
3937 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3939 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
3940 0, NULL);
3941 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
3943 hr = pMFTUnregisterLocal(NULL);
3944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3946 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
3947 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
3949 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
3950 0, NULL);
3951 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
3953 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
3954 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3957 START_TEST(mfplat)
3959 CoInitialize(NULL);
3961 init_functions();
3963 test_startup();
3964 test_register();
3965 test_media_type();
3966 test_MFCreateMediaEvent();
3967 test_attributes();
3968 test_sample();
3969 test_file_stream();
3970 test_MFCreateMFByteStreamOnStream();
3971 test_system_memory_buffer();
3972 test_source_resolver();
3973 test_MFCreateAsyncResult();
3974 test_allocate_queue();
3975 test_MFCopyImage();
3976 test_MFCreateCollection();
3977 test_MFHeapAlloc();
3978 test_scheduled_items();
3979 test_serial_queue();
3980 test_periodic_callback();
3981 test_event_queue();
3982 test_presentation_descriptor();
3983 test_system_time_source();
3984 test_MFInvokeCallback();
3985 test_stream_descriptor();
3986 test_MFCalculateImageSize();
3987 test_MFCompareFullToPartialMediaType();
3988 test_attributes_serialization();
3989 test_wrapped_media_type();
3990 test_MFCreateWaveFormatExFromMFMediaType();
3991 test_async_create_file();
3992 test_local_handlers();
3993 test_create_property_store();
3994 test_dxgi_device_manager();
3995 test_MFCreateTransformActivate();
3996 test_MFTRegisterLocal();
3998 CoUninitialize();