mfplat/tests: Add a workaround for test failures on Windows 7 VMs.
[wine.git] / dlls / mfplat / tests / mfplat.c
bloba548e30778332cb4c9782aea1f4562ae3cfbeb13
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"
37 #include "evr.h"
39 #include "wine/test.h"
40 #include "wine/heap.h"
42 #define D3D11_INIT_GUID
43 #include "initguid.h"
44 #include "d3d11_4.h"
45 #include "d3d9.h"
46 #include "d3d9types.h"
47 #include "ks.h"
48 #include "ksmedia.h"
50 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
51 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
52 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
53 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
55 extern const CLSID CLSID_FileSchemePlugin;
57 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
58 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
59 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
60 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
62 static BOOL is_win8_plus;
64 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
65 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
67 ULONG rc;
68 IUnknown_AddRef(obj);
69 rc = IUnknown_Release(obj);
70 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
73 static ULONG get_refcount(void *iface)
75 IUnknown *unknown = iface;
76 IUnknown_AddRef(unknown);
77 return IUnknown_Release(unknown);
80 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
81 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
83 IUnknown *iface = iface_ptr;
84 HRESULT hr, expected_hr;
85 IUnknown *unk;
87 expected_hr = supported ? S_OK : E_NOINTERFACE;
89 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
90 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
91 if (SUCCEEDED(hr))
92 IUnknown_Release(unk);
95 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
96 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
97 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
99 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
101 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
102 DWORD width, DWORD lines);
103 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
104 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
105 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
106 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
107 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
108 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
109 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
110 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
111 IMFActivate *activate);
112 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
113 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
114 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
115 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
116 const MFT_REGISTER_TYPE_INFO* output_types);
117 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
118 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
119 const MFT_REGISTER_TYPE_INFO *output_types);
120 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
121 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
122 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
123 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
124 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
125 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
126 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
127 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
128 IMFMediaBuffer **buffer);
129 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
130 DWORD min_alignment, IMFMediaBuffer **buffer);
131 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
132 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
133 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
134 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
135 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
136 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
137 IMFMediaBuffer **buffer);
139 static HWND create_window(void)
141 RECT r = {0, 0, 640, 480};
143 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
145 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
146 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
149 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
151 D3DPRESENT_PARAMETERS present_parameters = {0};
152 IDirect3DDevice9 *device = NULL;
154 present_parameters.BackBufferWidth = 640;
155 present_parameters.BackBufferHeight = 480;
156 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
157 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
158 present_parameters.hDeviceWindow = focus_window;
159 present_parameters.Windowed = TRUE;
160 present_parameters.EnableAutoDepthStencil = TRUE;
161 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
162 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
164 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
165 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
167 return device;
170 static const WCHAR fileschemeW[] = L"file://";
172 static WCHAR *load_resource(const WCHAR *name)
174 static WCHAR pathW[MAX_PATH];
175 DWORD written;
176 HANDLE file;
177 HRSRC res;
178 void *ptr;
180 GetTempPathW(ARRAY_SIZE(pathW), pathW);
181 lstrcatW(pathW, name);
183 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
184 NULL, CREATE_ALWAYS, 0, 0);
185 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
186 wine_dbgstr_w(pathW), GetLastError());
188 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
189 ok(res != 0, "couldn't find resource\n");
190 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
191 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
192 &written, NULL);
193 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
194 "couldn't write resource\n" );
195 CloseHandle(file);
197 return pathW;
200 struct test_callback
202 IMFAsyncCallback IMFAsyncCallback_iface;
203 HANDLE event;
204 DWORD param;
205 IMFMediaEvent *media_event;
208 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
210 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
213 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
215 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
216 IsEqualIID(riid, &IID_IUnknown))
218 *obj = iface;
219 IMFAsyncCallback_AddRef(iface);
220 return S_OK;
223 *obj = NULL;
224 return E_NOINTERFACE;
227 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
229 return 2;
232 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
234 return 1;
237 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
239 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
240 return E_NOTIMPL;
244 static BOOL check_clsid(CLSID *clsids, UINT32 count)
246 int i;
247 for (i = 0; i < count; i++)
249 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
250 return TRUE;
252 return FALSE;
255 static void test_register(void)
257 WCHAR name[] = L"Wine test";
258 MFT_REGISTER_TYPE_INFO input[] =
260 { DUMMY_CLSID, DUMMY_GUID1 }
262 MFT_REGISTER_TYPE_INFO output[] =
264 { DUMMY_CLSID, DUMMY_GUID2 }
266 CLSID *clsids;
267 UINT32 count;
268 HRESULT ret;
270 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
271 if (ret == E_ACCESSDENIED)
273 win_skip("Not enough permissions to register a filter\n");
274 return;
276 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
278 if(0)
280 /* NULL name crashes on windows */
281 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
282 ok(ret == E_INVALIDARG, "got %x\n", ret);
285 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
286 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
288 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
289 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
291 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
292 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
294 if(0)
296 /* NULL clsids/count crashes on windows (vista) */
297 count = 0;
298 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
299 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
300 ok(count == 0, "Expected count == 0\n");
302 clsids = NULL;
303 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
304 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
307 count = 0;
308 clsids = NULL;
309 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
310 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
311 ok(count > 0, "Expected count > 0\n");
312 ok(clsids != NULL, "Expected clsids != NULL\n");
313 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
314 CoTaskMemFree(clsids);
316 count = 0;
317 clsids = NULL;
318 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
319 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
320 ok(count > 0, "Expected count > 0\n");
321 ok(clsids != NULL, "Expected clsids != NULL\n");
322 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
323 CoTaskMemFree(clsids);
325 count = 0;
326 clsids = NULL;
327 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
328 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
329 ok(count > 0, "Expected count > 0\n");
330 ok(clsids != NULL, "Expected clsids != NULL\n");
331 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
332 CoTaskMemFree(clsids);
334 count = 0;
335 clsids = NULL;
336 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
337 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
338 ok(count > 0, "Expected count > 0\n");
339 ok(clsids != NULL, "Expected clsids != NULL\n");
340 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
341 CoTaskMemFree(clsids);
343 /* exchange input and output */
344 count = 0;
345 clsids = NULL;
346 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
347 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
348 ok(!count, "got %d\n", count);
349 ok(clsids == NULL, "Expected clsids == NULL\n");
351 ret = MFTUnregister(DUMMY_CLSID);
352 ok(ret == S_OK ||
353 /* w7pro64 */
354 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
356 ret = MFTUnregister(DUMMY_CLSID);
357 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
360 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
362 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
363 IMFSourceResolver *resolver;
364 IUnknown *object, *object2;
365 MF_OBJECT_TYPE obj_type;
366 HRESULT hr;
368 ok(!!result, "Unexpected result object.\n");
370 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
372 object = NULL;
373 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
374 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
376 hr = IMFAsyncResult_GetObject(result, &object2);
377 ok(hr == S_OK, "Failed to get result object, hr %#x.\n", hr);
378 ok(object2 == object, "Unexpected object.\n");
380 if (object)
381 IUnknown_Release(object);
382 IUnknown_Release(object2);
384 SetEvent(callback->event);
386 return S_OK;
389 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
391 testcallback_QueryInterface,
392 testcallback_AddRef,
393 testcallback_Release,
394 testcallback_GetParameters,
395 test_create_from_url_callback_Invoke,
398 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
400 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
401 IMFSchemeHandler *handler;
402 IUnknown *object, *object2;
403 MF_OBJECT_TYPE obj_type;
404 HRESULT hr;
406 ok(!!result, "Unexpected result object.\n");
408 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
410 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
411 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
413 if (SUCCEEDED(hr))
415 hr = IMFAsyncResult_GetObject(result, &object2);
416 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
418 IUnknown_Release(object);
421 SetEvent(callback->event);
423 return S_OK;
426 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
428 testcallback_QueryInterface,
429 testcallback_AddRef,
430 testcallback_Release,
431 testcallback_GetParameters,
432 test_create_from_file_handler_callback_Invoke,
435 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
437 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
438 IMFMediaEventGenerator *generator;
439 HRESULT hr;
441 ok(!!result, "Unexpected result object.\n");
443 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
445 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
446 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
448 SetEvent(callback->event);
450 return S_OK;
453 static const IMFAsyncCallbackVtbl events_callback_vtbl =
455 testcallback_QueryInterface,
456 testcallback_AddRef,
457 testcallback_Release,
458 testcallback_GetParameters,
459 source_events_callback_Invoke,
462 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
464 struct test_callback callback = {{ 0 }};
465 MediaEventType event_type;
466 BOOL ret = FALSE;
467 HRESULT hr;
469 callback.IMFAsyncCallback_iface.lpVtbl = &events_callback_vtbl;
470 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
472 for (;;)
474 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback.IMFAsyncCallback_iface,
475 (IUnknown *)generator);
476 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
478 if (WaitForSingleObject(callback.event, 1000) == WAIT_TIMEOUT)
480 ok(0, "timeout\n");
481 break;
484 Sleep(10);
486 hr = IMFMediaEvent_GetType(callback.media_event, &event_type);
487 ok(hr == S_OK, "Failed to event type, hr %#x.\n", hr);
489 if ((ret = (event_type == expected_event_type)))
491 if (value)
493 hr = IMFMediaEvent_GetValue(callback.media_event, value);
494 ok(hr == S_OK, "Failed to get value of event, hr %#x.\n", hr);
497 break;
501 CloseHandle(callback.event);
502 if (callback.media_event)
503 IMFMediaEvent_Release(callback.media_event);
505 return ret;
508 static void test_source_resolver(void)
510 struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
511 struct test_callback callback2 = { { &test_create_from_file_handler_callback_vtbl } };
512 IMFSourceResolver *resolver, *resolver2;
513 IMFPresentationDescriptor *descriptor;
514 IMFSchemeHandler *scheme_handler;
515 IMFMediaStream *video_stream;
516 IMFAttributes *attributes;
517 IMFMediaSource *mediasource;
518 IMFMediaTypeHandler *handler;
519 IMFMediaType *media_type;
520 BOOL selected, do_uninit;
521 MF_OBJECT_TYPE obj_type;
522 IMFStreamDescriptor *sd;
523 IUnknown *cancel_cookie;
524 IMFByteStream *stream;
525 WCHAR pathW[MAX_PATH];
526 int i, sample_count;
527 WCHAR *filename;
528 PROPVARIANT var;
529 HRESULT hr;
530 GUID guid;
532 if (!pMFCreateSourceResolver)
534 win_skip("MFCreateSourceResolver() not found\n");
535 return;
538 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
539 ok(hr == S_OK, "got 0x%08x\n", hr);
541 hr = pMFCreateSourceResolver(NULL);
542 ok(hr == E_POINTER, "got %#x\n", hr);
544 hr = pMFCreateSourceResolver(&resolver);
545 ok(hr == S_OK, "got %#x\n", hr);
547 hr = pMFCreateSourceResolver(&resolver2);
548 ok(hr == S_OK, "got %#x\n", hr);
549 ok(resolver != resolver2, "Expected new instance\n");
551 IMFSourceResolver_Release(resolver2);
553 filename = load_resource(L"test.mp4");
555 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
556 ok(hr == S_OK, "got 0x%08x\n", hr);
558 hr = IMFSourceResolver_CreateObjectFromByteStream(
559 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
560 &obj_type, (IUnknown **)&mediasource);
561 ok(hr == E_POINTER, "got 0x%08x\n", hr);
563 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
564 NULL, (IUnknown **)&mediasource);
565 ok(hr == E_POINTER, "got 0x%08x\n", hr);
567 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
568 &obj_type, NULL);
569 ok(hr == E_POINTER, "got 0x%08x\n", hr);
571 IMFByteStream_Release(stream);
573 /* Create from URL. */
574 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
576 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
577 (IUnknown **)&stream);
578 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#x.\n", hr);
580 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
581 (IUnknown **)&stream);
582 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
583 IMFByteStream_Release(stream);
585 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
586 &cancel_cookie, &callback.IMFAsyncCallback_iface, (IUnknown *)resolver);
587 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
588 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
589 IUnknown_Release(cancel_cookie);
591 if (SUCCEEDED(hr))
592 WaitForSingleObject(callback.event, INFINITE);
594 /* With explicit scheme. */
595 lstrcpyW(pathW, fileschemeW);
596 lstrcatW(pathW, filename);
598 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
599 (IUnknown **)&stream);
600 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
601 IMFByteStream_Release(stream);
603 /* We have to create a new bytestream here, because all following
604 * calls to CreateObjectFromByteStream will fail. */
605 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
606 ok(hr == S_OK, "got 0x%08x\n", hr);
608 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
609 ok(hr == S_OK, "got 0x%08x\n", hr);
610 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
611 ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr);
612 IMFAttributes_Release(attributes);
614 /* Start of gstreamer dependent tests */
616 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
617 &obj_type, (IUnknown **)&mediasource);
618 if (strcmp(winetest_platform, "wine"))
619 ok(hr == S_OK, "got 0x%08x\n", hr);
620 if (FAILED(hr))
622 IMFByteStream_Release(stream);
623 IMFSourceResolver_Release(resolver);
625 hr = MFShutdown();
626 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
628 DeleteFileW(filename);
629 return;
631 ok(mediasource != NULL, "got %p\n", mediasource);
632 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
634 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
635 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
636 ok(descriptor != NULL, "got %p\n", descriptor);
638 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
639 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
641 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
642 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
643 IMFStreamDescriptor_Release(sd);
645 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
646 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
648 /* Check major/minor type for the test media. */
649 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
651 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
652 ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
653 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
654 ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
655 todo_wine
656 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
657 IMFMediaType_Release(media_type);
659 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
660 ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr);
662 var.vt = VT_EMPTY;
663 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
664 ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
666 video_stream = NULL;
667 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
669 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
670 video_stream = (IMFMediaStream *)var.punkVal;
673 sample_count = 10;
675 for (i = 0; i < sample_count; ++i)
677 hr = IMFMediaStream_RequestSample(video_stream, NULL);
678 if (i == sample_count)
679 break;
680 ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
681 if (hr != S_OK)
682 break;
685 for (i = 0; i < sample_count; ++i)
687 static const LONGLONG MILLI_TO_100_NANO = 10000;
688 LONGLONG duration, time;
689 DWORD buffer_count;
690 IMFSample *sample;
691 BOOL ret;
693 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
694 ok(ret, "Sample %u not received.\n", i + 1);
695 if (!ret)
696 break;
698 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
699 sample = (IMFSample *)var.punkVal;
701 hr = IMFSample_GetBufferCount(sample, &buffer_count);
702 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
703 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
705 hr = IMFSample_GetSampleDuration(sample, &duration);
706 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
707 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
709 hr = IMFSample_GetSampleTime(sample, &time);
710 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
711 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
713 IMFSample_Release(sample);
716 if (i == sample_count)
718 IMFMediaEvent *event;
720 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
721 Sleep(100);
722 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
723 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
725 hr = IMFMediaStream_RequestSample(video_stream, NULL);
726 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
727 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
731 hr = IMFMediaStream_RequestSample(video_stream, NULL);
732 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
734 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
736 IMFMediaStream_Release(video_stream);
737 IMFMediaTypeHandler_Release(handler);
738 IMFPresentationDescriptor_Release(descriptor);
740 hr = IMFMediaSource_Shutdown(mediasource);
741 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
743 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
744 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
746 IMFMediaSource_Release(mediasource);
747 IMFByteStream_Release(stream);
749 /* Create directly through scheme handler. */
750 hr = CoInitialize(NULL);
751 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
752 do_uninit = hr == S_OK;
754 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
755 (void **)&scheme_handler);
756 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
758 callback2.event = callback.event;
759 cancel_cookie = NULL;
760 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
761 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
762 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
763 ok(!!cancel_cookie, "Unexpected cancel object.\n");
764 IUnknown_Release(cancel_cookie);
766 WaitForSingleObject(callback2.event, INFINITE);
768 IMFSchemeHandler_Release(scheme_handler);
770 if (do_uninit)
771 CoUninitialize();
773 CloseHandle(callback.event);
775 IMFSourceResolver_Release(resolver);
777 hr = MFShutdown();
778 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
780 DeleteFileW(filename);
783 static void init_functions(void)
785 HMODULE mod = GetModuleHandleA("mfplat.dll");
787 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
788 X(MFAddPeriodicCallback);
789 X(MFAllocateSerialWorkQueue);
790 X(MFAllocateWorkQueueEx);
791 X(MFCopyImage);
792 X(MFCreate2DMediaBuffer);
793 X(MFCreateDXGIDeviceManager);
794 X(MFCreateDXGISurfaceBuffer);
795 X(MFCreateDXSurfaceBuffer);
796 X(MFCreateSourceResolver);
797 X(MFCreateMediaBufferFromMediaType);
798 X(MFCreateMFByteStreamOnStream);
799 X(MFCreateTrackedSample);
800 X(MFCreateTransformActivate);
801 X(MFCreateVideoSampleAllocatorEx);
802 X(MFGetPlaneSize);
803 X(MFGetStrideForBitmapInfoHeader);
804 X(MFMapDX9FormatToDXGIFormat);
805 X(MFMapDXGIFormatToDX9Format);
806 X(MFPutWaitingWorkItem);
807 X(MFRegisterLocalByteStreamHandler);
808 X(MFRegisterLocalSchemeHandler);
809 X(MFRemovePeriodicCallback);
810 X(MFTEnumEx);
811 X(MFTRegisterLocal);
812 X(MFTRegisterLocalByCLSID);
813 X(MFTUnregisterLocal);
814 X(MFTUnregisterLocalByCLSID);
816 if ((mod = LoadLibraryA("d3d11.dll")))
818 X(D3D11CreateDevice);
821 mod = GetModuleHandleA("ole32.dll");
823 X(CoGetApartmentType);
824 #undef X
826 is_win8_plus = pMFPutWaitingWorkItem != NULL;
829 static void test_media_type(void)
831 IMFMediaType *mediatype, *mediatype2;
832 IMFVideoMediaType *video_type;
833 IUnknown *unk, *unk2;
834 DWORD count, flags;
835 BOOL compressed;
836 HRESULT hr;
837 GUID guid;
839 if(0)
841 /* Crash on Windows Vista/7 */
842 hr = MFCreateMediaType(NULL);
843 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
846 hr = MFCreateMediaType(&mediatype);
847 ok(hr == S_OK, "got 0x%08x\n", hr);
849 hr = IMFMediaType_GetMajorType(mediatype, &guid);
850 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
852 compressed = FALSE;
853 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
854 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
855 ok(compressed, "Unexpected value %d.\n", compressed);
857 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
858 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
860 compressed = FALSE;
861 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
862 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
863 ok(compressed, "Unexpected value %d.\n", compressed);
865 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
866 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
868 compressed = TRUE;
869 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
870 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
871 ok(!compressed, "Unexpected value %d.\n", compressed);
873 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
874 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
876 hr = IMFMediaType_GetMajorType(mediatype, &guid);
877 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
878 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
880 /* IsEqual() */
881 hr = MFCreateMediaType(&mediatype2);
882 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
884 flags = 0xdeadbeef;
885 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
886 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
887 ok(flags == 0, "Unexpected flags %#x.\n", flags);
889 /* Different major types. */
890 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
891 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
893 flags = 0;
894 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
895 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
896 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
897 "Unexpected flags %#x.\n", flags);
899 /* Same major types, different subtypes. */
900 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
901 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
903 flags = 0;
904 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
906 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
907 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
909 /* Different user data. */
910 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
911 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
913 flags = 0;
914 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
915 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
916 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
917 "Unexpected flags %#x.\n", flags);
919 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
920 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
922 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
923 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
925 flags = 0;
926 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
927 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
928 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
929 "Unexpected flags %#x.\n", flags);
931 IMFMediaType_Release(mediatype2);
932 IMFMediaType_Release(mediatype);
934 /* IMFVideoMediaType */
935 hr = MFCreateMediaType(&mediatype);
936 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
938 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
940 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
941 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
942 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
943 IUnknown_Release(unk);
945 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
946 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
948 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
949 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
951 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
953 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
954 IUnknown_Release(unk2);
956 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
957 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
958 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
959 IUnknown_Release(unk2);
961 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
962 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
963 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
964 IUnknown_Release(unk2);
966 IUnknown_Release(unk);
968 hr = MFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
969 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
971 check_interface(video_type, &IID_IMFMediaType, TRUE);
972 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
974 /* Major and subtype are set on creation. */
975 hr = IMFVideoMediaType_GetCount(video_type, &count);
976 ok(count == 2, "Unexpected attribute count %#x.\n", hr);
978 hr = IMFVideoMediaType_DeleteAllItems(video_type);
979 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
981 hr = IMFVideoMediaType_GetCount(video_type, &count);
982 ok(!count, "Unexpected attribute count %#x.\n", hr);
984 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
986 IMFVideoMediaType_Release(video_type);
988 IMFMediaType_Release(mediatype);
990 /* IMFAudioMediaType */
991 hr = MFCreateMediaType(&mediatype);
992 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
994 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
996 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
997 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
998 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
999 IUnknown_Release(unk);
1001 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1002 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1004 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1005 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1007 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1008 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1009 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1010 IUnknown_Release(unk2);
1012 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1013 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1014 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1015 IUnknown_Release(unk2);
1017 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1018 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1019 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1020 IUnknown_Release(unk2);
1022 IUnknown_Release(unk);
1024 IMFMediaType_Release(mediatype);
1027 static void test_MFCreateMediaEvent(void)
1029 HRESULT hr;
1030 IMFMediaEvent *mediaevent;
1032 MediaEventType type;
1033 GUID extended_type;
1034 HRESULT status;
1035 PROPVARIANT value;
1037 PropVariantInit(&value);
1038 value.vt = VT_UNKNOWN;
1040 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1041 ok(hr == S_OK, "got 0x%08x\n", hr);
1043 PropVariantClear(&value);
1045 hr = IMFMediaEvent_GetType(mediaevent, &type);
1046 ok(hr == S_OK, "got 0x%08x\n", hr);
1047 ok(type == MEError, "got %#x\n", type);
1049 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1050 ok(hr == S_OK, "got 0x%08x\n", hr);
1051 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1052 wine_dbgstr_guid(&extended_type));
1054 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1055 ok(hr == S_OK, "got 0x%08x\n", hr);
1056 ok(status == E_FAIL, "got 0x%08x\n", status);
1058 PropVariantInit(&value);
1059 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1060 ok(hr == S_OK, "got 0x%08x\n", hr);
1061 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1062 PropVariantClear(&value);
1064 IMFMediaEvent_Release(mediaevent);
1066 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1067 ok(hr == S_OK, "got 0x%08x\n", hr);
1069 hr = IMFMediaEvent_GetType(mediaevent, &type);
1070 ok(hr == S_OK, "got 0x%08x\n", hr);
1071 ok(type == MEUnknown, "got %#x\n", type);
1073 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1074 ok(hr == S_OK, "got 0x%08x\n", hr);
1075 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1076 wine_dbgstr_guid(&extended_type));
1078 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1079 ok(hr == S_OK, "got 0x%08x\n", hr);
1080 ok(status == S_OK, "got 0x%08x\n", status);
1082 PropVariantInit(&value);
1083 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1084 ok(hr == S_OK, "got 0x%08x\n", hr);
1085 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1086 PropVariantClear(&value);
1088 IMFMediaEvent_Release(mediaevent);
1091 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1092 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1094 UINT32 count = expected + 1;
1095 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1096 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1097 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1100 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1101 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1103 MF_ATTRIBUTE_TYPE type;
1104 HRESULT hr;
1106 hr = IMFAttributes_GetItemType(obj, key, &type);
1107 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1108 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1111 static void test_attributes(void)
1113 static const WCHAR stringW[] = L"Wine";
1114 static const UINT8 blob[] = {0,1,2,3,4,5};
1115 IMFAttributes *attributes, *attributes1;
1116 UINT8 blob_value[256], *blob_buf = NULL;
1117 MF_ATTRIBUTES_MATCH_TYPE match_type;
1118 UINT32 value, string_length, size;
1119 PROPVARIANT propvar, ret_propvar;
1120 MF_ATTRIBUTE_TYPE type;
1121 double double_value;
1122 IUnknown *unk_value;
1123 WCHAR bufferW[256];
1124 UINT64 value64;
1125 WCHAR *string;
1126 BOOL result;
1127 HRESULT hr;
1128 GUID key;
1130 hr = MFCreateAttributes( &attributes, 3 );
1131 ok(hr == S_OK, "got 0x%08x\n", hr);
1133 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1134 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1136 CHECK_ATTR_COUNT(attributes, 0);
1137 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1138 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
1139 CHECK_ATTR_COUNT(attributes, 1);
1140 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1142 value = 0xdeadbeef;
1143 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1144 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
1145 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1147 value64 = 0xdeadbeef;
1148 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1149 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1150 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1152 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1153 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
1154 CHECK_ATTR_COUNT(attributes, 1);
1155 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1157 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1158 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
1159 ok(value64 == 65536, "Unexpected value.\n");
1161 value = 0xdeadbeef;
1162 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1163 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1164 ok(value == 0xdeadbeef, "Unexpected value.\n");
1166 IMFAttributes_Release(attributes);
1168 hr = MFCreateAttributes(&attributes, 0);
1169 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1171 PropVariantInit(&propvar);
1172 propvar.vt = MF_ATTRIBUTE_UINT32;
1173 U(propvar).ulVal = 123;
1174 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1175 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1176 PropVariantInit(&ret_propvar);
1177 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1178 U(ret_propvar).ulVal = 0xdeadbeef;
1179 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1180 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1181 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1182 PropVariantClear(&ret_propvar);
1183 CHECK_ATTR_COUNT(attributes, 1);
1185 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1186 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
1188 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1189 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1191 PropVariantInit(&ret_propvar);
1192 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1193 U(ret_propvar).pwszVal = NULL;
1194 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1195 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1196 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1197 PropVariantClear(&ret_propvar);
1199 PropVariantClear(&propvar);
1201 PropVariantInit(&propvar);
1202 propvar.vt = MF_ATTRIBUTE_UINT64;
1203 U(propvar).uhVal.QuadPart = 65536;
1204 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1205 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1206 PropVariantInit(&ret_propvar);
1207 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1208 U(ret_propvar).ulVal = 0xdeadbeef;
1209 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1210 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1211 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1212 PropVariantClear(&ret_propvar);
1213 PropVariantClear(&propvar);
1214 CHECK_ATTR_COUNT(attributes, 1);
1216 PropVariantInit(&propvar);
1217 propvar.vt = VT_I4;
1218 U(propvar).lVal = 123;
1219 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1220 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
1221 PropVariantInit(&ret_propvar);
1222 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1223 U(ret_propvar).lVal = 0xdeadbeef;
1224 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1225 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1226 PropVariantClear(&propvar);
1227 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1228 PropVariantClear(&ret_propvar);
1230 PropVariantInit(&propvar);
1231 propvar.vt = MF_ATTRIBUTE_UINT32;
1232 U(propvar).ulVal = 123;
1233 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1234 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1236 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1237 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1238 CHECK_ATTR_COUNT(attributes, 2);
1240 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1241 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1242 CHECK_ATTR_COUNT(attributes, 2);
1244 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1245 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1246 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1247 PropVariantClear(&ret_propvar);
1248 PropVariantClear(&propvar);
1250 propvar.vt = MF_ATTRIBUTE_UINT64;
1251 U(propvar).uhVal.QuadPart = 65536;
1253 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1254 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1255 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1256 PropVariantClear(&ret_propvar);
1257 PropVariantClear(&propvar);
1259 /* Item ordering is not consistent across Windows version. */
1260 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1261 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1262 PropVariantClear(&ret_propvar);
1264 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1265 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1266 PropVariantClear(&ret_propvar);
1268 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1269 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
1270 CHECK_ATTR_COUNT(attributes, 3);
1271 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1273 double_value = 0xdeadbeef;
1274 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1275 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
1276 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1278 propvar.vt = MF_ATTRIBUTE_UINT64;
1279 U(propvar).uhVal.QuadPart = 22;
1280 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1281 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1282 ok(!result, "Unexpected result.\n");
1284 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1285 U(propvar).dblVal = 22.0;
1286 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1287 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1288 ok(result, "Unexpected result.\n");
1290 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1291 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
1292 CHECK_ATTR_COUNT(attributes, 3);
1293 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1295 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1296 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
1297 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1299 string_length = 0xdeadbeef;
1300 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1301 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
1302 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1303 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1304 CoTaskMemFree(string);
1306 string_length = 0xdeadbeef;
1307 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1308 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1309 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1310 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1311 memset(bufferW, 0, sizeof(bufferW));
1313 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1314 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1315 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1316 memset(bufferW, 0, sizeof(bufferW));
1318 string_length = 0;
1319 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1320 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1321 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1322 ok(string_length, "Unexpected length.\n");
1324 string_length = 0xdeadbeef;
1325 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1326 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1327 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1329 /* VT_UNKNOWN */
1330 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1331 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1332 CHECK_ATTR_COUNT(attributes, 4);
1333 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1335 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1336 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1337 IUnknown_Release(unk_value);
1339 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1340 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1341 IUnknown_Release(unk_value);
1343 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1344 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1346 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1347 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1348 CHECK_ATTR_COUNT(attributes, 5);
1350 unk_value = NULL;
1351 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1352 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1354 /* CopyAllItems() */
1355 hr = MFCreateAttributes(&attributes1, 0);
1356 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1357 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1358 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1359 CHECK_ATTR_COUNT(attributes, 5);
1360 CHECK_ATTR_COUNT(attributes1, 5);
1362 hr = IMFAttributes_DeleteAllItems(attributes1);
1363 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
1364 CHECK_ATTR_COUNT(attributes1, 0);
1366 propvar.vt = MF_ATTRIBUTE_UINT64;
1367 U(propvar).uhVal.QuadPart = 22;
1368 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1369 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1370 ok(!result, "Unexpected result.\n");
1372 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1373 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1374 CHECK_ATTR_COUNT(attributes, 0);
1376 /* Blob */
1377 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1378 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
1379 CHECK_ATTR_COUNT(attributes, 1);
1380 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1381 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1382 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1383 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1385 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1386 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1388 size = 0;
1389 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1390 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1391 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1392 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1394 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1395 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1397 memset(blob_value, 0, sizeof(blob_value));
1398 size = 0;
1399 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1400 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1401 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1402 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1403 CoTaskMemFree(blob_buf);
1405 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1406 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1408 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1409 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1411 IMFAttributes_Release(attributes);
1412 IMFAttributes_Release(attributes1);
1414 /* Compare() */
1415 hr = MFCreateAttributes(&attributes, 0);
1416 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1417 hr = MFCreateAttributes(&attributes1, 0);
1418 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1420 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1421 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1423 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1425 result = FALSE;
1426 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1427 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1428 ok(result, "Unexpected result %d.\n", result);
1430 result = FALSE;
1431 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1432 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1433 ok(result, "Unexpected result %d.\n", result);
1436 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1437 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1439 result = TRUE;
1440 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1441 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1442 ok(!result, "Unexpected result %d.\n", result);
1444 result = TRUE;
1445 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1446 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1447 ok(!result, "Unexpected result %d.\n", result);
1449 result = FALSE;
1450 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1451 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1452 ok(result, "Unexpected result %d.\n", result);
1454 result = FALSE;
1455 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1456 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1457 ok(result, "Unexpected result %d.\n", result);
1459 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1460 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1462 result = TRUE;
1463 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1464 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1465 ok(!result, "Unexpected result %d.\n", result);
1467 result = TRUE;
1468 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1469 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1470 ok(!result, "Unexpected result %d.\n", result);
1472 result = TRUE;
1473 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1474 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1475 ok(!result, "Unexpected result %d.\n", result);
1477 result = TRUE;
1478 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1479 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1480 ok(!result, "Unexpected result %d.\n", result);
1482 result = TRUE;
1483 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1484 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1485 ok(!result, "Unexpected result %d.\n", result);
1487 result = TRUE;
1488 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1489 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1490 ok(!result, "Unexpected result %d.\n", result);
1492 result = TRUE;
1493 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1494 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1495 ok(!result, "Unexpected result %d.\n", result);
1497 result = TRUE;
1498 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1499 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1500 ok(!result, "Unexpected result %d.\n", result);
1502 result = TRUE;
1503 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1504 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1505 ok(!result, "Unexpected result %d.\n", result);
1507 result = TRUE;
1508 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1509 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1510 ok(!result, "Unexpected result %d.\n", result);
1512 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1513 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1515 result = FALSE;
1516 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1517 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1518 ok(result, "Unexpected result %d.\n", result);
1520 result = FALSE;
1521 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1522 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1523 ok(result, "Unexpected result %d.\n", result);
1525 result = FALSE;
1526 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1527 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1528 ok(result, "Unexpected result %d.\n", result);
1530 result = FALSE;
1531 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1532 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1533 ok(result, "Unexpected result %d.\n", result);
1535 result = FALSE;
1536 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1537 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1538 ok(result, "Unexpected result %d.\n", result);
1540 result = FALSE;
1541 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1542 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1543 ok(result, "Unexpected result %d.\n", result);
1545 result = FALSE;
1546 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1547 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1548 ok(result, "Unexpected result %d.\n", result);
1550 result = FALSE;
1551 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1552 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1553 ok(result, "Unexpected result %d.\n", result);
1555 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1556 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1558 result = TRUE;
1559 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1560 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1561 ok(!result, "Unexpected result %d.\n", result);
1563 result = TRUE;
1564 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1565 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1566 ok(!result, "Unexpected result %d.\n", result);
1568 result = FALSE;
1569 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1570 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1571 ok(result, "Unexpected result %d.\n", result);
1573 result = FALSE;
1574 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1575 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1576 ok(result, "Unexpected result %d.\n", result);
1578 result = FALSE;
1579 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1580 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1581 ok(result, "Unexpected result %d.\n", result);
1583 result = TRUE;
1584 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1585 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1586 ok(!result, "Unexpected result %d.\n", result);
1588 result = FALSE;
1589 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1590 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1591 ok(result, "Unexpected result %d.\n", result);
1593 result = TRUE;
1594 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1595 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1596 ok(!result, "Unexpected result %d.\n", result);
1598 result = FALSE;
1599 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1600 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1601 ok(result, "Unexpected result %d.\n", result);
1603 result = FALSE;
1604 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1605 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1606 ok(result, "Unexpected result %d.\n", result);
1608 IMFAttributes_Release(attributes);
1609 IMFAttributes_Release(attributes1);
1612 static void test_MFCreateMFByteStreamOnStream(void)
1614 IMFByteStream *bytestream;
1615 IMFByteStream *bytestream2;
1616 IStream *stream;
1617 IMFAttributes *attributes = NULL;
1618 DWORD caps, written, count;
1619 IUnknown *unknown;
1620 ULONG ref, size;
1621 HRESULT hr;
1623 if(!pMFCreateMFByteStreamOnStream)
1625 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1626 return;
1629 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1630 ok(hr == S_OK, "got 0x%08x\n", hr);
1632 caps = 0xffff0000;
1633 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1634 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1636 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1637 ok(hr == S_OK, "got 0x%08x\n", hr);
1639 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1640 (void **)&unknown);
1641 ok(hr == S_OK, "got 0x%08x\n", hr);
1642 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1643 ref = IUnknown_Release(unknown);
1644 ok(ref == 1, "got %u\n", ref);
1646 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1647 (void **)&bytestream2);
1648 ok(hr == S_OK, "got 0x%08x\n", hr);
1649 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1650 ref = IMFByteStream_Release(bytestream2);
1651 ok(ref == 1, "got %u\n", ref);
1653 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1654 (void **)&attributes);
1655 ok(hr == S_OK ||
1656 /* w7pro64 */
1657 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1659 if (hr != S_OK)
1661 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1662 IStream_Release(stream);
1663 IMFByteStream_Release(bytestream);
1664 return;
1667 ok(attributes != NULL, "got NULL\n");
1668 hr = IMFAttributes_GetCount(attributes, &count);
1669 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1670 ok(count == 0, "Unexpected attributes count %u.\n", count);
1672 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1673 (void **)&unknown);
1674 ok(hr == S_OK, "got 0x%08x\n", hr);
1675 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1676 ref = IUnknown_Release(unknown);
1677 ok(ref == 2, "got %u\n", ref);
1679 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1680 (void **)&bytestream2);
1681 ok(hr == S_OK, "got 0x%08x\n", hr);
1682 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1683 ref = IMFByteStream_Release(bytestream2);
1684 ok(ref == 2, "got %u\n", ref);
1686 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1687 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1688 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1689 check_interface(bytestream, &IID_IMFGetService, FALSE);
1691 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1692 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1693 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1695 hr = IMFByteStream_Close(bytestream);
1696 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1698 hr = IMFByteStream_Close(bytestream);
1699 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1701 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1702 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1703 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1705 caps = 0;
1706 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1707 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1708 ok(caps == 0xffff0000, "Unexpected content.\n");
1710 IMFAttributes_Release(attributes);
1711 IMFByteStream_Release(bytestream);
1712 IStream_Release(stream);
1715 static void test_file_stream(void)
1717 static const WCHAR newfilename[] = L"new.mp4";
1718 IMFByteStream *bytestream, *bytestream2;
1719 QWORD bytestream_length, position;
1720 IMFAttributes *attributes = NULL;
1721 MF_ATTRIBUTE_TYPE item_type;
1722 WCHAR pathW[MAX_PATH];
1723 DWORD caps, count;
1724 WCHAR *filename;
1725 HRESULT hr;
1726 WCHAR *str;
1727 BOOL eos;
1729 filename = load_resource(L"test.mp4");
1731 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1732 ok(hr == S_OK, "got 0x%08x\n", hr);
1734 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1735 MF_FILEFLAGS_NONE, filename, &bytestream);
1736 ok(hr == S_OK, "got 0x%08x\n", hr);
1738 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1739 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1740 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1741 check_interface(bytestream, &IID_IMFGetService, TRUE);
1743 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1744 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1745 if (is_win8_plus)
1747 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1748 "Unexpected caps %#x.\n", caps);
1750 else
1751 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1753 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1754 (void **)&attributes);
1755 ok(hr == S_OK, "got 0x%08x\n", hr);
1756 ok(attributes != NULL, "got NULL\n");
1758 hr = IMFAttributes_GetCount(attributes, &count);
1759 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1760 ok(count == 2, "Unexpected attributes count %u.\n", count);
1762 /* Original file name. */
1763 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1764 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1765 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1766 CoTaskMemFree(str);
1768 /* Modification time. */
1769 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1770 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1771 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1773 IMFAttributes_Release(attributes);
1775 /* Length. */
1776 hr = IMFByteStream_GetLength(bytestream, NULL);
1777 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1779 bytestream_length = 0;
1780 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1781 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1782 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1784 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1785 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1787 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1788 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1789 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1791 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1792 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1794 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1795 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1797 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1798 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1799 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1801 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1802 MF_FILEFLAGS_NONE, filename, &bytestream2);
1803 ok(hr == S_OK, "got 0x%08x\n", hr);
1804 IMFByteStream_Release(bytestream2);
1806 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1807 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1809 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1810 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1812 IMFByteStream_Release(bytestream);
1814 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1815 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1816 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1818 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1819 MF_FILEFLAGS_NONE, filename, &bytestream);
1820 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1822 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1823 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1824 ok(hr == S_OK, "got 0x%08x\n", hr);
1826 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1827 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1829 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1830 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1832 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1833 newfilename, &bytestream2);
1834 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1836 IMFByteStream_Release(bytestream);
1838 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1839 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1840 ok(hr == S_OK, "got 0x%08x\n", hr);
1842 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1843 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1844 newfilename, &bytestream2);
1845 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1847 IMFByteStream_Release(bytestream);
1849 /* Explicit file: scheme */
1850 lstrcpyW(pathW, fileschemeW);
1851 lstrcatW(pathW, filename);
1852 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
1853 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1855 hr = MFShutdown();
1856 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1858 DeleteFileW(filename);
1859 DeleteFileW(newfilename);
1862 static void test_system_memory_buffer(void)
1864 IMFMediaBuffer *buffer;
1865 HRESULT hr;
1866 DWORD length, max;
1867 BYTE *data, *data2;
1869 hr = MFCreateMemoryBuffer(1024, NULL);
1870 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1872 hr = MFCreateMemoryBuffer(0, &buffer);
1873 ok(hr == S_OK, "got 0x%08x\n", hr);
1874 if(buffer)
1876 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1877 ok(hr == S_OK, "got 0x%08x\n", hr);
1878 ok(length == 0, "got %u\n", length);
1880 IMFMediaBuffer_Release(buffer);
1883 hr = MFCreateMemoryBuffer(1024, &buffer);
1884 ok(hr == S_OK, "got 0x%08x\n", hr);
1886 check_interface(buffer, &IID_IMFGetService, FALSE);
1888 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
1889 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1891 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1892 ok(hr == S_OK, "got 0x%08x\n", hr);
1893 ok(length == 1024, "got %u\n", length);
1895 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
1896 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
1898 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1899 ok(hr == S_OK, "got 0x%08x\n", hr);
1901 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
1902 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1904 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1905 ok(hr == S_OK, "got 0x%08x\n", hr);
1906 ok(length == 10, "got %u\n", length);
1908 length = 0;
1909 max = 0;
1910 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
1911 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1912 ok(length == 0, "got %u\n", length);
1913 ok(max == 0, "got %u\n", length);
1915 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1916 ok(hr == S_OK, "got 0x%08x\n", hr);
1917 ok(length == 10, "got %u\n", length);
1918 ok(max == 1024, "got %u\n", max);
1920 /* Attempt to lock the buffer twice */
1921 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
1922 ok(hr == S_OK, "got 0x%08x\n", hr);
1923 ok(data == data2, "got 0x%08x\n", hr);
1925 hr = IMFMediaBuffer_Unlock(buffer);
1926 ok(hr == S_OK, "got 0x%08x\n", hr);
1928 hr = IMFMediaBuffer_Unlock(buffer);
1929 ok(hr == S_OK, "got 0x%08x\n", hr);
1931 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
1932 ok(hr == S_OK, "got 0x%08x\n", hr);
1934 hr = IMFMediaBuffer_Unlock(buffer);
1935 ok(hr == S_OK, "got 0x%08x\n", hr);
1937 /* Extra Unlock */
1938 hr = IMFMediaBuffer_Unlock(buffer);
1939 ok(hr == S_OK, "got 0x%08x\n", hr);
1941 IMFMediaBuffer_Release(buffer);
1943 /* Aligned buffer. */
1944 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
1945 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1947 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
1948 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
1950 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1951 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1952 ok(length == 0, "Unexpected current length %u.\n", length);
1954 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
1955 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1956 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
1957 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
1958 ok(length == 1, "Unexpected current length %u.\n", length);
1960 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1961 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1962 ok(length == 201, "Unexpected max length %u.\n", length);
1964 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
1965 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1966 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1967 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
1968 ok(length == 201, "Unexpected max length %u.\n", length);
1969 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
1970 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
1972 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
1973 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
1974 ok(max == 201 && length == 10, "Unexpected length.\n");
1975 hr = IMFMediaBuffer_Unlock(buffer);
1976 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
1978 IMFMediaBuffer_Release(buffer);
1981 static void test_sample(void)
1983 static const DWORD test_pattern = 0x22222222;
1984 IMFMediaBuffer *buffer, *buffer2, *buffer3;
1985 DWORD count, flags, length;
1986 IMFAttributes *attributes;
1987 IMFSample *sample;
1988 LONGLONG time;
1989 HRESULT hr;
1990 BYTE *data;
1992 hr = MFCreateSample( &sample );
1993 ok(hr == S_OK, "got 0x%08x\n", hr);
1995 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
1996 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
1998 CHECK_ATTR_COUNT(attributes, 0);
2000 hr = IMFSample_GetBufferCount(sample, NULL);
2001 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2003 hr = IMFSample_GetBufferCount(sample, &count);
2004 ok(hr == S_OK, "got 0x%08x\n", hr);
2005 ok(count == 0, "got %d\n", count);
2007 hr = IMFSample_GetSampleFlags(sample, &flags);
2008 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2009 ok(!flags, "Unexpected flags %#x.\n", flags);
2011 hr = IMFSample_SetSampleFlags(sample, 0x123);
2012 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
2013 hr = IMFSample_GetSampleFlags(sample, &flags);
2014 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2015 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2017 hr = IMFSample_GetSampleTime(sample, &time);
2018 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2020 hr = IMFSample_GetSampleDuration(sample, &time);
2021 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2023 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2024 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2026 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2027 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2029 hr = IMFSample_RemoveAllBuffers(sample);
2030 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
2032 hr = IMFSample_GetTotalLength(sample, &length);
2033 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2034 ok(!length, "Unexpected total length %u.\n", length);
2036 hr = MFCreateMemoryBuffer(16, &buffer);
2037 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
2039 hr = IMFSample_AddBuffer(sample, buffer);
2040 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2042 hr = IMFSample_AddBuffer(sample, buffer);
2043 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2045 hr = IMFSample_GetBufferCount(sample, &count);
2046 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2047 ok(count == 2, "Unexpected buffer count %u.\n", count);
2049 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2050 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
2051 ok(buffer2 == buffer, "Unexpected object.\n");
2052 IMFMediaBuffer_Release(buffer2);
2054 hr = IMFSample_GetTotalLength(sample, &length);
2055 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2056 ok(!length, "Unexpected total length %u.\n", length);
2058 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2059 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2061 hr = IMFSample_GetTotalLength(sample, &length);
2062 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2063 ok(length == 4, "Unexpected total length %u.\n", length);
2065 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2066 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
2068 hr = IMFSample_GetTotalLength(sample, &length);
2069 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2070 ok(length == 2, "Unexpected total length %u.\n", length);
2072 IMFMediaBuffer_Release(buffer);
2074 /* Duration */
2075 hr = IMFSample_SetSampleDuration(sample, 10);
2076 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
2077 CHECK_ATTR_COUNT(attributes, 0);
2078 hr = IMFSample_GetSampleDuration(sample, &time);
2079 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
2080 ok(time == 10, "Unexpected duration.\n");
2082 /* Timestamp */
2083 hr = IMFSample_SetSampleTime(sample, 1);
2084 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
2085 CHECK_ATTR_COUNT(attributes, 0);
2086 hr = IMFSample_GetSampleTime(sample, &time);
2087 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
2088 ok(time == 1, "Unexpected timestamp.\n");
2090 IMFAttributes_Release(attributes);
2091 IMFSample_Release(sample);
2093 /* CopyToBuffer() */
2094 hr = MFCreateSample(&sample);
2095 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2097 hr = MFCreateMemoryBuffer(16, &buffer2);
2098 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2100 /* Sample with no buffers. */
2101 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2102 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2103 hr = IMFSample_CopyToBuffer(sample, buffer2);
2104 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2105 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2106 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2107 ok(!length, "Unexpected length %u.\n", length);
2109 /* Single buffer, larger destination. */
2110 hr = MFCreateMemoryBuffer(8, &buffer);
2111 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2113 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2114 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2115 *(DWORD *)data = 0x11111111;
2116 hr = IMFMediaBuffer_Unlock(buffer);
2117 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2118 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2119 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2121 hr = IMFSample_AddBuffer(sample, buffer);
2122 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2124 /* Existing content is overwritten. */
2125 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2126 ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
2128 hr = IMFSample_CopyToBuffer(sample, buffer2);
2129 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2131 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2132 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2133 ok(length == 4, "Unexpected buffer length %u.\n", length);
2135 /* Multiple buffers, matching total size. */
2136 hr = IMFSample_AddBuffer(sample, buffer);
2137 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2139 hr = IMFSample_GetBufferCount(sample, &count);
2140 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2141 ok(count == 2, "Unexpected buffer count %u.\n", count);
2143 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2144 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2146 hr = IMFSample_CopyToBuffer(sample, buffer2);
2147 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2149 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2150 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2151 ok(length == 16, "Unexpected buffer length %u.\n", length);
2153 hr = IMFSample_AddBuffer(sample, buffer);
2154 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2156 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2157 ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
2159 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2160 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2161 *(DWORD *)data = test_pattern;
2162 hr = IMFMediaBuffer_Unlock(buffer2);
2163 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2165 hr = IMFSample_CopyToBuffer(sample, buffer2);
2166 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
2168 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2169 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2170 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
2171 hr = IMFMediaBuffer_Unlock(buffer2);
2172 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2174 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2175 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2176 ok(!length, "Unexpected buffer length %u.\n", length);
2178 IMFMediaBuffer_Release(buffer2);
2179 IMFSample_Release(sample);
2181 /* ConvertToContiguousBuffer() */
2182 hr = MFCreateSample(&sample);
2183 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2185 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2186 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2188 hr = MFCreateMemoryBuffer(16, &buffer);
2189 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2191 hr = IMFSample_AddBuffer(sample, buffer);
2192 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2194 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2195 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2196 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2197 IMFMediaBuffer_Release(buffer2);
2199 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2200 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2202 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2203 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2204 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2205 IMFMediaBuffer_Release(buffer2);
2207 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2208 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2210 hr = MFCreateMemoryBuffer(16, &buffer2);
2211 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2213 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2216 hr = IMFSample_AddBuffer(sample, buffer2);
2217 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2218 IMFMediaBuffer_Release(buffer2);
2220 hr = IMFSample_GetBufferCount(sample, &count);
2221 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2222 ok(count == 2, "Unexpected buffer count %u.\n", count);
2224 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2225 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2227 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2228 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2229 ok(length == 7, "Unexpected length %u.\n", length);
2231 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2232 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2233 ok(length == 7, "Unexpected length %u.\n", length);
2235 IMFMediaBuffer_Release(buffer3);
2237 hr = IMFSample_GetBufferCount(sample, &count);
2238 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2239 ok(count == 1, "Unexpected buffer count %u.\n", count);
2241 hr = IMFSample_AddBuffer(sample, buffer);
2242 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2244 hr = IMFSample_GetBufferCount(sample, &count);
2245 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2246 ok(count == 2, "Unexpected buffer count %u.\n", count);
2248 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2249 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2251 hr = IMFSample_GetBufferCount(sample, &count);
2252 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2253 ok(count == 1, "Unexpected buffer count %u.\n", count);
2255 IMFMediaBuffer_Release(buffer);
2257 IMFSample_Release(sample);
2260 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2262 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2263 IMFMediaEventQueue *queue;
2264 IUnknown *state, *obj;
2265 HRESULT hr;
2267 ok(result != NULL, "Unexpected result object.\n");
2269 state = IMFAsyncResult_GetStateNoAddRef(result);
2270 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2272 IMFMediaEvent *event = NULL, *event2;
2274 if (is_win8_plus)
2276 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2277 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2279 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2280 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2282 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2283 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
2285 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2286 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
2288 if (event)
2289 IMFMediaEvent_Release(event);
2292 hr = IMFAsyncResult_GetObject(result, &obj);
2293 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2295 IMFMediaEventQueue_Release(queue);
2297 SetEvent(callback->event);
2300 return E_NOTIMPL;
2303 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2305 testcallback_QueryInterface,
2306 testcallback_AddRef,
2307 testcallback_Release,
2308 testcallback_GetParameters,
2309 testcallback_Invoke,
2312 static void init_test_callback(struct test_callback *callback)
2314 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
2315 callback->event = NULL;
2318 static void test_MFCreateAsyncResult(void)
2320 IMFAsyncResult *result, *result2;
2321 struct test_callback callback;
2322 IUnknown *state, *object;
2323 MFASYNCRESULT *data;
2324 ULONG refcount;
2325 HANDLE event;
2326 DWORD flags;
2327 HRESULT hr;
2328 BOOL ret;
2330 init_test_callback(&callback);
2332 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2333 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2335 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2336 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2338 data = (MFASYNCRESULT *)result;
2339 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2340 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2341 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2342 ok(data->hEvent == NULL, "Unexpected event.\n");
2344 hr = IMFAsyncResult_GetState(result, NULL);
2345 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2347 state = (void *)0xdeadbeef;
2348 hr = IMFAsyncResult_GetState(result, &state);
2349 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2350 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2352 hr = IMFAsyncResult_GetStatus(result);
2353 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
2355 data->hrStatusResult = 123;
2356 hr = IMFAsyncResult_GetStatus(result);
2357 ok(hr == 123, "Unexpected status %#x.\n", hr);
2359 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2360 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
2361 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
2363 hr = IMFAsyncResult_GetObject(result, NULL);
2364 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2366 object = (void *)0xdeadbeef;
2367 hr = IMFAsyncResult_GetObject(result, &object);
2368 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
2369 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2371 state = IMFAsyncResult_GetStateNoAddRef(result);
2372 ok(state == NULL, "Unexpected state.\n");
2374 /* Object. */
2375 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
2376 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2378 data = (MFASYNCRESULT *)result2;
2379 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2380 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2381 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2382 ok(data->hEvent == NULL, "Unexpected event.\n");
2384 object = NULL;
2385 hr = IMFAsyncResult_GetObject(result2, &object);
2386 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
2387 ok(object == (IUnknown *)result, "Unexpected object.\n");
2388 IUnknown_Release(object);
2390 IMFAsyncResult_Release(result2);
2392 /* State object. */
2393 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2394 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2396 data = (MFASYNCRESULT *)result2;
2397 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2398 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2399 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2400 ok(data->hEvent == NULL, "Unexpected event.\n");
2402 state = NULL;
2403 hr = IMFAsyncResult_GetState(result2, &state);
2404 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
2405 ok(state == (IUnknown *)result, "Unexpected state.\n");
2406 IUnknown_Release(state);
2408 state = IMFAsyncResult_GetStateNoAddRef(result2);
2409 ok(state == (IUnknown *)result, "Unexpected state.\n");
2411 refcount = IMFAsyncResult_Release(result2);
2412 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2413 refcount = IMFAsyncResult_Release(result);
2414 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2416 /* Event handle is closed on release. */
2417 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2418 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2420 data = (MFASYNCRESULT *)result;
2421 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2422 ok(data->hEvent != NULL, "Failed to create event.\n");
2423 ret = GetHandleInformation(event, &flags);
2424 ok(ret, "Failed to get handle info.\n");
2426 refcount = IMFAsyncResult_Release(result);
2427 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2428 ret = GetHandleInformation(event, &flags);
2429 ok(!ret, "Expected handle to be closed.\n");
2431 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2432 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2434 data = (MFASYNCRESULT *)result;
2435 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2436 ok(data->hEvent != NULL, "Failed to create event.\n");
2437 ret = GetHandleInformation(event, &flags);
2438 ok(ret, "Failed to get handle info.\n");
2440 refcount = IMFAsyncResult_Release(result);
2441 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2442 ret = GetHandleInformation(event, &flags);
2443 ok(!ret, "Expected handle to be closed.\n");
2446 static void test_startup(void)
2448 DWORD queue;
2449 HRESULT hr;
2451 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2452 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
2454 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2455 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2457 hr = MFAllocateWorkQueue(&queue);
2458 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2459 hr = MFUnlockWorkQueue(queue);
2460 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2462 hr = MFShutdown();
2463 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2465 hr = MFAllocateWorkQueue(&queue);
2466 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2468 /* Already shut down, has no effect. */
2469 hr = MFShutdown();
2470 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2472 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2473 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2475 hr = MFAllocateWorkQueue(&queue);
2476 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2477 hr = MFUnlockWorkQueue(queue);
2478 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2480 hr = MFShutdown();
2481 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2483 /* Platform lock. */
2484 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2485 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2487 hr = MFAllocateWorkQueue(&queue);
2488 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2489 hr = MFUnlockWorkQueue(queue);
2490 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2492 /* Unlocking implies shutdown. */
2493 hr = MFUnlockPlatform();
2494 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2496 hr = MFAllocateWorkQueue(&queue);
2497 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2499 hr = MFLockPlatform();
2500 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2502 hr = MFAllocateWorkQueue(&queue);
2503 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2504 hr = MFUnlockWorkQueue(queue);
2505 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2507 hr = MFShutdown();
2508 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2511 static void test_allocate_queue(void)
2513 DWORD queue, queue2;
2514 HRESULT hr;
2516 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2517 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2519 hr = MFAllocateWorkQueue(&queue);
2520 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2521 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2523 hr = MFUnlockWorkQueue(queue);
2524 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2526 hr = MFUnlockWorkQueue(queue);
2527 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2529 hr = MFAllocateWorkQueue(&queue2);
2530 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2531 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2533 hr = MFUnlockWorkQueue(queue2);
2534 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2536 /* Unlock in system queue range. */
2537 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2538 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2540 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2541 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2543 hr = MFUnlockWorkQueue(0x20);
2544 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2546 hr = MFShutdown();
2547 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2550 static void test_MFCopyImage(void)
2552 BYTE dest[16], src[16];
2553 HRESULT hr;
2555 if (!pMFCopyImage)
2557 win_skip("MFCopyImage() is not available.\n");
2558 return;
2561 memset(dest, 0xaa, sizeof(dest));
2562 memset(src, 0x11, sizeof(src));
2564 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2565 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2566 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2568 memset(dest, 0xaa, sizeof(dest));
2569 memset(src, 0x11, sizeof(src));
2571 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2572 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2573 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2575 memset(dest, 0xaa, sizeof(dest));
2576 memset(src, 0x11, sizeof(src));
2578 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2579 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2580 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2583 static void test_MFCreateCollection(void)
2585 IMFCollection *collection;
2586 IUnknown *element;
2587 DWORD count;
2588 HRESULT hr;
2590 hr = MFCreateCollection(NULL);
2591 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2593 hr = MFCreateCollection(&collection);
2594 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2596 hr = IMFCollection_GetElementCount(collection, NULL);
2597 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2599 count = 1;
2600 hr = IMFCollection_GetElementCount(collection, &count);
2601 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2602 ok(count == 0, "Unexpected count %u.\n", count);
2604 hr = IMFCollection_GetElement(collection, 0, NULL);
2605 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2607 element = (void *)0xdeadbeef;
2608 hr = IMFCollection_GetElement(collection, 0, &element);
2609 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2610 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2612 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2613 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2615 element = (void *)0xdeadbeef;
2616 hr = IMFCollection_RemoveElement(collection, 0, &element);
2617 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2618 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2620 hr = IMFCollection_RemoveAllElements(collection);
2621 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2623 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2624 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2626 count = 0;
2627 hr = IMFCollection_GetElementCount(collection, &count);
2628 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2629 ok(count == 1, "Unexpected count %u.\n", count);
2631 hr = IMFCollection_AddElement(collection, NULL);
2632 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2634 count = 0;
2635 hr = IMFCollection_GetElementCount(collection, &count);
2636 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2637 ok(count == 2, "Unexpected count %u.\n", count);
2639 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2640 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2642 count = 0;
2643 hr = IMFCollection_GetElementCount(collection, &count);
2644 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2645 ok(count == 11, "Unexpected count %u.\n", count);
2647 hr = IMFCollection_GetElement(collection, 0, &element);
2648 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2649 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2650 IUnknown_Release(element);
2652 hr = IMFCollection_GetElement(collection, 1, &element);
2653 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2654 ok(!element, "Unexpected element.\n");
2656 hr = IMFCollection_GetElement(collection, 2, &element);
2657 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2658 ok(!element, "Unexpected element.\n");
2660 hr = IMFCollection_GetElement(collection, 10, &element);
2661 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2662 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2663 IUnknown_Release(element);
2665 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2666 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2668 hr = IMFCollection_GetElement(collection, 0, &element);
2669 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2671 hr = IMFCollection_RemoveAllElements(collection);
2672 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2674 count = 1;
2675 hr = IMFCollection_GetElementCount(collection, &count);
2676 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2677 ok(count == 0, "Unexpected count %u.\n", count);
2679 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2680 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2682 IMFCollection_Release(collection);
2685 static void test_MFHeapAlloc(void)
2687 void *res;
2689 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2690 ok(res != NULL, "MFHeapAlloc failed.\n");
2692 MFHeapFree(res);
2695 static void test_scheduled_items(void)
2697 struct test_callback callback;
2698 IMFAsyncResult *result;
2699 MFWORKITEM_KEY key, key2;
2700 HRESULT hr;
2702 init_test_callback(&callback);
2704 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2705 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2707 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2708 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2710 hr = MFCancelWorkItem(key);
2711 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2713 hr = MFCancelWorkItem(key);
2714 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2716 if (!pMFPutWaitingWorkItem)
2718 win_skip("Waiting items are not supported.\n");
2719 return;
2722 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2723 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2725 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2726 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2728 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2729 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2731 hr = MFCancelWorkItem(key);
2732 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2734 hr = MFCancelWorkItem(key2);
2735 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2737 IMFAsyncResult_Release(result);
2739 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2740 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2742 hr = MFCancelWorkItem(key);
2743 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2745 hr = MFShutdown();
2746 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2749 static void test_serial_queue(void)
2751 static const DWORD queue_ids[] =
2753 MFASYNC_CALLBACK_QUEUE_STANDARD,
2754 MFASYNC_CALLBACK_QUEUE_RT,
2755 MFASYNC_CALLBACK_QUEUE_IO,
2756 MFASYNC_CALLBACK_QUEUE_TIMER,
2757 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2758 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2760 DWORD queue, serial_queue;
2761 unsigned int i;
2762 HRESULT hr;
2764 if (!pMFAllocateSerialWorkQueue)
2766 win_skip("Serial queues are not supported.\n");
2767 return;
2770 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2771 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2773 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2775 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2776 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2778 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2779 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2780 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2782 if (SUCCEEDED(hr))
2784 hr = MFUnlockWorkQueue(serial_queue);
2785 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2789 /* Chain them together. */
2790 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2791 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2793 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2794 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2796 hr = MFUnlockWorkQueue(serial_queue);
2797 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2799 hr = MFUnlockWorkQueue(queue);
2800 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2802 hr = MFShutdown();
2803 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2806 static LONG periodic_counter;
2807 static void CALLBACK periodic_callback(IUnknown *context)
2809 InterlockedIncrement(&periodic_counter);
2812 static void test_periodic_callback(void)
2814 DWORD period, key;
2815 HRESULT hr;
2817 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2818 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2820 period = 0;
2821 hr = MFGetTimerPeriodicity(&period);
2822 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2823 ok(period == 10, "Unexpected period %u.\n", period);
2825 if (!pMFAddPeriodicCallback)
2827 win_skip("Periodic callbacks are not supported.\n");
2828 hr = MFShutdown();
2829 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2830 return;
2833 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2835 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2836 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2837 ok(key != 0, "Unexpected key %#x.\n", key);
2839 Sleep(10 * period);
2841 hr = pMFRemovePeriodicCallback(key);
2842 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2844 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2846 hr = MFShutdown();
2847 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2850 static void test_event_queue(void)
2852 struct test_callback callback, callback2;
2853 IMFMediaEvent *event, *event2;
2854 IMFMediaEventQueue *queue;
2855 IMFAsyncResult *result;
2856 HRESULT hr;
2857 DWORD ret;
2859 init_test_callback(&callback);
2860 init_test_callback(&callback2);
2862 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2863 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2865 hr = MFCreateEventQueue(&queue);
2866 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
2868 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2869 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2871 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2872 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2874 if (is_win8_plus)
2876 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2877 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2879 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
2880 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2881 ok(event2 == event, "Unexpected event object.\n");
2882 IMFMediaEvent_Release(event2);
2884 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2885 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2887 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
2888 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2889 IMFMediaEvent_Release(event2);
2892 /* Async case. */
2893 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2894 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2896 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2897 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
2899 /* Same callback, same state. */
2900 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
2901 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2903 /* Same callback, different state. */
2904 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
2905 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
2907 /* Different callback, same state. */
2908 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
2909 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2911 /* Different callback, different state. */
2912 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
2913 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
2915 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
2917 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2918 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2920 ret = WaitForSingleObject(callback.event, 500);
2921 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
2923 CloseHandle(callback.event);
2925 IMFMediaEvent_Release(event);
2927 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2928 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2930 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2931 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
2933 /* Shutdown behavior. */
2934 hr = IMFMediaEventQueue_Shutdown(queue);
2935 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2937 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2938 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2940 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2941 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2942 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2943 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2944 IMFMediaEvent_Release(event);
2946 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2947 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2949 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
2950 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2952 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
2953 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2955 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
2956 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2958 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2959 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2960 IMFAsyncResult_Release(result);
2962 /* Already shut down. */
2963 hr = IMFMediaEventQueue_Shutdown(queue);
2964 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2966 IMFMediaEventQueue_Release(queue);
2968 hr = MFShutdown();
2969 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2972 static void test_presentation_descriptor(void)
2974 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
2975 IMFPresentationDescriptor *pd, *pd2;
2976 IMFMediaType *media_type;
2977 unsigned int i;
2978 BOOL selected;
2979 UINT64 value;
2980 DWORD count;
2981 HRESULT hr;
2983 hr = MFCreateMediaType(&media_type);
2984 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
2986 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
2988 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
2989 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
2992 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
2993 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
2995 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
2996 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
2998 for (i = 0; i < count; ++i)
3000 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3001 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3002 ok(!selected, "Unexpected selected state.\n");
3003 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3004 IMFStreamDescriptor_Release(stream_desc2);
3007 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3008 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3010 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3011 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3013 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3014 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
3016 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3017 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3018 ok(!!selected, "Unexpected selected state.\n");
3019 IMFStreamDescriptor_Release(stream_desc2);
3021 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3022 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3024 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3025 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
3027 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3028 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3029 ok(!!selected, "Unexpected selected state.\n");
3030 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3031 IMFStreamDescriptor_Release(stream_desc2);
3033 value = 0;
3034 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3035 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3036 ok(value == 1, "Unexpected attribute value.\n");
3038 IMFPresentationDescriptor_Release(pd2);
3039 IMFPresentationDescriptor_Release(pd);
3041 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3043 IMFStreamDescriptor_Release(stream_desc[i]);
3046 /* Partially initialized array. */
3047 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3048 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3049 stream_desc[0] = NULL;
3051 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3052 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3054 IMFStreamDescriptor_Release(stream_desc[1]);
3055 IMFMediaType_Release(media_type);
3058 enum clock_action
3060 CLOCK_START,
3061 CLOCK_STOP,
3062 CLOCK_PAUSE,
3063 CLOCK_RESTART,
3066 static void test_system_time_source(void)
3068 static const struct clock_state_test
3070 enum clock_action action;
3071 MFCLOCK_STATE state;
3072 BOOL is_invalid;
3074 clock_state_change[] =
3076 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3077 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3078 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3079 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3080 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3081 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3082 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3083 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3084 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3085 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3086 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3087 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3088 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3089 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3090 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3091 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3092 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3094 IMFPresentationTimeSource *time_source, *time_source2;
3095 IMFClockStateSink *statesink;
3096 IMFClock *clock, *clock2;
3097 MFCLOCK_PROPERTIES props;
3098 MFCLOCK_STATE state;
3099 unsigned int i;
3100 MFTIME systime;
3101 LONGLONG time;
3102 DWORD value;
3103 HRESULT hr;
3105 hr = MFCreateSystemTimeSource(&time_source);
3106 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3108 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3109 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
3110 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3111 "Unexpected flags %#x.\n", value);
3113 value = 1;
3114 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3115 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3116 ok(value == 0, "Unexpected value %u.\n", value);
3118 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3119 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
3120 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3122 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3123 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
3125 /* State changes. */
3126 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3128 switch (clock_state_change[i].action)
3130 case CLOCK_STOP:
3131 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3132 break;
3133 case CLOCK_RESTART:
3134 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3135 break;
3136 case CLOCK_PAUSE:
3137 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3138 break;
3139 case CLOCK_START:
3140 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3141 break;
3142 default:
3145 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
3146 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3147 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
3148 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3151 IMFClockStateSink_Release(statesink);
3153 /* Properties. */
3154 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3155 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3157 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3158 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3160 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3161 wine_dbgstr_longlong(props.qwCorrelationRate));
3162 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3163 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3164 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3165 wine_dbgstr_longlong(props.qwClockFrequency));
3166 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3167 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3169 /* Underlying clock. */
3170 hr = MFCreateSystemTimeSource(&time_source2);
3171 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3172 EXPECT_REF(time_source2, 1);
3173 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3174 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3175 EXPECT_REF(time_source2, 1);
3176 EXPECT_REF(clock2, 2);
3178 EXPECT_REF(time_source, 1);
3179 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3180 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3181 EXPECT_REF(time_source, 1);
3182 EXPECT_REF(clock, 2);
3184 ok(clock != clock2, "Unexpected clock instance.\n");
3186 IMFPresentationTimeSource_Release(time_source2);
3187 IMFClock_Release(clock2);
3189 hr = IMFClock_GetClockCharacteristics(clock, &value);
3190 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
3191 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3192 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
3194 hr = IMFClock_GetContinuityKey(clock, &value);
3195 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
3196 ok(value == 0, "Unexpected key value %u.\n", value);
3198 hr = IMFClock_GetState(clock, 0, &state);
3199 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
3200 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3202 hr = IMFClock_GetProperties(clock, &props);
3203 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3205 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3206 wine_dbgstr_longlong(props.qwCorrelationRate));
3207 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3208 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3209 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3210 wine_dbgstr_longlong(props.qwClockFrequency));
3211 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3212 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3214 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3215 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
3216 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3218 IMFClock_Release(clock);
3220 /* Test returned time regarding specified rate and offset. */
3221 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3222 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3224 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3225 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
3226 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3228 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3229 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3230 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3232 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3233 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3235 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3236 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3237 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3239 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3240 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3242 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3243 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3244 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3245 wine_dbgstr_longlong(systime));
3247 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3248 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3250 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3251 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3252 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3254 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3255 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3257 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3258 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3259 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3260 wine_dbgstr_longlong(systime));
3262 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3263 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3265 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3266 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3267 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3268 wine_dbgstr_longlong(systime));
3270 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3271 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3273 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3274 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3275 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3277 /* Increased rate. */
3278 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3279 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
3281 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3282 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3284 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3285 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3286 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3287 wine_dbgstr_longlong(2 * systime));
3289 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3290 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3292 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3293 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3294 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3295 wine_dbgstr_longlong(2 * systime));
3297 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3298 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3300 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3301 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3302 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3303 wine_dbgstr_longlong(systime));
3305 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3306 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3308 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3309 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3310 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3311 wine_dbgstr_longlong(systime));
3313 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3314 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3316 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3317 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3318 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3319 wine_dbgstr_longlong(systime));
3321 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3322 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3324 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3325 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3326 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3328 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3329 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3331 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3332 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3333 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3334 wine_dbgstr_longlong(2 * systime));
3336 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3337 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3339 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3340 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3342 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3343 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3344 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3345 wine_dbgstr_longlong(2 * systime));
3347 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3348 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3350 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3351 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3352 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3353 wine_dbgstr_longlong(systime));
3355 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3356 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3358 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3359 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3360 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3361 wine_dbgstr_longlong(systime));
3363 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3364 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3366 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3367 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3368 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3369 wine_dbgstr_longlong(systime));
3371 IMFClockStateSink_Release(statesink);
3372 IMFPresentationTimeSource_Release(time_source);
3374 /* PRESENTATION_CURRENT_POSITION */
3375 hr = MFCreateSystemTimeSource(&time_source);
3376 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3378 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3379 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3381 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3382 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3383 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3384 wine_dbgstr_longlong(systime));
3386 /* INVALID -> RUNNING */
3387 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3388 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3390 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3391 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3392 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3393 wine_dbgstr_longlong(systime));
3395 /* RUNNING -> RUNNING */
3396 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3397 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3399 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3400 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3401 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3402 wine_dbgstr_longlong(systime));
3404 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3405 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3407 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3408 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3409 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3410 wine_dbgstr_longlong(systime));
3412 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3413 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3415 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3416 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3417 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3418 wine_dbgstr_longlong(systime));
3420 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3421 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3423 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3424 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3425 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3426 wine_dbgstr_longlong(systime));
3428 /* STOPPED -> RUNNING */
3429 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3430 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3432 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3433 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3434 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3435 wine_dbgstr_longlong(systime));
3437 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3438 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3440 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3441 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3442 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3443 wine_dbgstr_longlong(systime));
3445 /* PAUSED -> RUNNING */
3446 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3447 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3449 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3450 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3451 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3452 wine_dbgstr_longlong(systime));
3454 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3455 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3457 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3458 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3459 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3460 wine_dbgstr_longlong(systime));
3462 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3463 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3465 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3466 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3467 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3468 wine_dbgstr_longlong(systime));
3470 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3471 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3473 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3474 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3475 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3476 wine_dbgstr_longlong(systime));
3478 IMFClockStateSink_Release(statesink);
3479 IMFPresentationTimeSource_Release(time_source);
3482 static void test_MFInvokeCallback(void)
3484 struct test_callback callback;
3485 IMFAsyncResult *result;
3486 MFASYNCRESULT *data;
3487 ULONG refcount;
3488 HRESULT hr;
3489 DWORD ret;
3491 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3492 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3494 init_test_callback(&callback);
3496 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3497 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3499 data = (MFASYNCRESULT *)result;
3500 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3501 ok(data->hEvent != NULL, "Failed to create event.\n");
3503 hr = MFInvokeCallback(result);
3504 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
3506 ret = WaitForSingleObject(data->hEvent, 100);
3507 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
3509 refcount = IMFAsyncResult_Release(result);
3510 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3512 hr = MFShutdown();
3513 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3516 static void test_stream_descriptor(void)
3518 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3519 IMFMediaTypeHandler *type_handler;
3520 IMFStreamDescriptor *stream_desc;
3521 GUID major_type;
3522 DWORD id, count;
3523 unsigned int i;
3524 HRESULT hr;
3526 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3527 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3529 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3531 hr = MFCreateMediaType(&media_types[i]);
3532 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3535 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3536 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3538 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3539 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3541 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3542 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
3543 ok(id == 123, "Unexpected id %#x.\n", id);
3545 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3546 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3548 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3549 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3550 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3552 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3553 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3555 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3556 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3558 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3560 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3561 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3562 ok(media_type == media_types[i], "Unexpected object.\n");
3564 if (SUCCEEDED(hr))
3565 IMFMediaType_Release(media_type);
3568 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
3569 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3571 /* IsMediaTypeSupported() */
3573 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3574 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3576 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
3577 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3579 hr = MFCreateMediaType(&media_type);
3580 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3582 hr = MFCreateMediaType(&media_type3);
3583 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3585 media_type2 = (void *)0xdeadbeef;
3586 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3587 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3588 ok(!media_type2, "Unexpected pointer.\n");
3590 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3591 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3593 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3594 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3596 media_type2 = (void *)0xdeadbeef;
3597 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3598 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3599 ok(!media_type2, "Unexpected pointer.\n");
3601 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3602 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3604 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3605 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3607 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3608 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3609 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
3611 /* Mismatching major types. */
3612 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3613 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3615 media_type2 = (void *)0xdeadbeef;
3616 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3617 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3618 ok(!media_type2, "Unexpected pointer.\n");
3620 /* Subtype missing. */
3621 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3622 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3624 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3625 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3627 media_type2 = (void *)0xdeadbeef;
3628 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3629 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3630 ok(!media_type2, "Unexpected pointer.\n");
3632 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3633 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3635 media_type2 = (void *)0xdeadbeef;
3636 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3637 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3638 ok(!media_type2, "Unexpected pointer.\n");
3640 /* Mismatching subtype. */
3641 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3642 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3644 media_type2 = (void *)0xdeadbeef;
3645 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3646 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3647 ok(!media_type2, "Unexpected pointer.\n");
3649 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3650 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3651 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3653 IMFMediaTypeHandler_Release(type_handler);
3654 IMFStreamDescriptor_Release(stream_desc);
3656 /* IsMediaTypeSupported() for unset current type. */
3657 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3658 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3660 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3661 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3663 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
3664 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3666 /* Initialize one from initial type set. */
3667 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
3668 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3670 media_type2 = (void *)0xdeadbeef;
3671 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3672 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3673 ok(!media_type2, "Unexpected pointer.\n");
3675 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3676 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3678 media_type2 = (void *)0xdeadbeef;
3679 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3680 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3681 ok(!media_type2, "Unexpected pointer.\n");
3683 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3684 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3686 media_type2 = (void *)0xdeadbeef;
3687 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3688 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3689 ok(!media_type2, "Unexpected pointer.\n");
3691 /* Now set current type that's not compatible. */
3692 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3693 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3695 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3696 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3698 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
3699 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3701 media_type2 = (void *)0xdeadbeef;
3702 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3703 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3704 ok(!media_type2, "Unexpected pointer.\n");
3706 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
3707 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3709 media_type2 = (void *)0xdeadbeef;
3710 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3711 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3712 ok(!media_type2, "Unexpected pointer.\n");
3714 IMFMediaType_Release(media_type);
3715 IMFMediaType_Release(media_type3);
3717 IMFMediaTypeHandler_Release(type_handler);
3719 IMFStreamDescriptor_Release(stream_desc);
3721 /* Major type is returned for first entry. */
3722 hr = MFCreateMediaType(&media_types[0]);
3723 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3724 hr = MFCreateMediaType(&media_types[1]);
3725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3727 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3728 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3729 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3730 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3732 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
3733 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3735 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3736 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3738 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3739 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3740 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3742 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3743 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3744 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3745 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3747 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3748 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3749 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3751 IMFMediaType_Release(media_types[0]);
3752 IMFMediaType_Release(media_types[1]);
3754 IMFMediaTypeHandler_Release(type_handler);
3755 IMFStreamDescriptor_Release(stream_desc);
3758 static void test_MFCalculateImageSize(void)
3760 static const struct image_size_test
3762 const GUID *subtype;
3763 UINT32 width;
3764 UINT32 height;
3765 UINT32 size;
3766 UINT32 plane_size; /* Matches image size when 0. */
3768 image_size_tests[] =
3770 { &MFVideoFormat_RGB8, 3, 5, 20 },
3771 { &MFVideoFormat_RGB8, 1, 1, 4 },
3772 { &MFVideoFormat_RGB555, 3, 5, 40 },
3773 { &MFVideoFormat_RGB555, 1, 1, 4 },
3774 { &MFVideoFormat_RGB565, 3, 5, 40 },
3775 { &MFVideoFormat_RGB565, 1, 1, 4 },
3776 { &MFVideoFormat_RGB24, 3, 5, 60 },
3777 { &MFVideoFormat_RGB24, 1, 1, 4 },
3778 { &MFVideoFormat_RGB32, 3, 5, 60 },
3779 { &MFVideoFormat_RGB32, 1, 1, 4 },
3780 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3781 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3782 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3783 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3784 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3785 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3787 /* YUV */
3788 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
3789 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
3790 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
3791 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
3792 { &MFVideoFormat_NV12, 4, 2, 12 },
3793 { &MFVideoFormat_NV12, 320, 240, 115200 },
3794 { &MFVideoFormat_AYUV, 1, 1, 4 },
3795 { &MFVideoFormat_AYUV, 2, 1, 8 },
3796 { &MFVideoFormat_AYUV, 1, 2, 8 },
3797 { &MFVideoFormat_AYUV, 4, 3, 48 },
3798 { &MFVideoFormat_AYUV, 320, 240, 307200 },
3799 { &MFVideoFormat_IMC1, 1, 1, 4 },
3800 { &MFVideoFormat_IMC1, 2, 1, 4 },
3801 { &MFVideoFormat_IMC1, 1, 2, 8 },
3802 { &MFVideoFormat_IMC1, 4, 3, 24 },
3803 { &MFVideoFormat_IMC1, 320, 240, 153600 },
3804 { &MFVideoFormat_IMC3, 1, 1, 4 },
3805 { &MFVideoFormat_IMC3, 2, 1, 4 },
3806 { &MFVideoFormat_IMC3, 1, 2, 8 },
3807 { &MFVideoFormat_IMC3, 4, 3, 24 },
3808 { &MFVideoFormat_IMC3, 320, 240, 153600 },
3809 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
3810 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
3811 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
3812 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
3813 { &MFVideoFormat_IMC2, 4, 2, 12 },
3814 { &MFVideoFormat_IMC2, 320, 240, 115200 },
3815 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
3816 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
3817 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
3818 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
3819 { &MFVideoFormat_IMC4, 4, 2, 12 },
3820 { &MFVideoFormat_IMC4, 320, 240, 115200 },
3821 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
3822 { &MFVideoFormat_YV12, 2, 1, 3 },
3823 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
3824 { &MFVideoFormat_YV12, 4, 3, 18 },
3825 { &MFVideoFormat_YV12, 320, 240, 115200 },
3827 { &MFVideoFormat_I420, 1, 1, 3, 1 },
3828 { &MFVideoFormat_I420, 2, 1, 3 },
3829 { &MFVideoFormat_I420, 1, 2, 6, 3 },
3830 { &MFVideoFormat_I420, 4, 3, 18 },
3831 { &MFVideoFormat_I420, 320, 240, 115200 },
3833 { &MFVideoFormat_YUY2, 2, 1, 4 },
3834 { &MFVideoFormat_YUY2, 4, 3, 24 },
3835 { &MFVideoFormat_YUY2, 128, 128, 32768 },
3836 { &MFVideoFormat_YUY2, 320, 240, 153600 },
3838 { &MFVideoFormat_UYVY, 2, 1, 4 },
3839 { &MFVideoFormat_UYVY, 4, 3, 24 },
3840 { &MFVideoFormat_UYVY, 128, 128, 32768 },
3841 { &MFVideoFormat_UYVY, 320, 240, 153600 },
3843 unsigned int i;
3844 UINT32 size;
3845 HRESULT hr;
3847 if (!pMFGetPlaneSize)
3848 win_skip("MFGetPlaneSize() is not available.\n");
3850 size = 1;
3851 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
3852 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
3853 ok(size == 0, "Unexpected size %u.\n", size);
3855 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
3857 const struct image_size_test *ptr = &image_size_tests[i];
3859 /* Those are supported since Win10. */
3860 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
3861 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
3863 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
3864 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
3865 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
3866 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
3868 if (pMFGetPlaneSize)
3870 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
3872 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
3873 ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
3874 ok(size == plane_size, "%u: unexpected plane size %u, expected %u.\n", i, size, plane_size);
3879 static void test_MFCompareFullToPartialMediaType(void)
3881 IMFMediaType *full_type, *partial_type;
3882 HRESULT hr;
3883 BOOL ret;
3885 hr = MFCreateMediaType(&full_type);
3886 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3888 hr = MFCreateMediaType(&partial_type);
3889 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3891 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3892 ok(!ret, "Unexpected result %d.\n", ret);
3894 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3895 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3897 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3898 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3900 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3901 ok(ret, "Unexpected result %d.\n", ret);
3903 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
3904 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3906 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3907 ok(ret, "Unexpected result %d.\n", ret);
3909 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
3910 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3912 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
3913 ok(!ret, "Unexpected result %d.\n", ret);
3915 IMFMediaType_Release(full_type);
3916 IMFMediaType_Release(partial_type);
3919 static void test_attributes_serialization(void)
3921 static const UINT8 blob[] = {1,2,3};
3922 IMFAttributes *attributes, *dest;
3923 UINT32 size, count, value32;
3924 double value_dbl;
3925 UINT64 value64;
3926 UINT8 *buffer;
3927 IUnknown *obj;
3928 HRESULT hr;
3929 WCHAR *str;
3930 GUID guid;
3932 hr = MFCreateAttributes(&attributes, 0);
3933 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3935 hr = MFCreateAttributes(&dest, 0);
3936 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3938 hr = MFGetAttributesAsBlobSize(attributes, &size);
3939 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3940 ok(size == 8, "Got size %u.\n", size);
3942 buffer = heap_alloc(size);
3944 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3945 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3947 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
3948 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
3950 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
3951 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3953 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
3954 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3956 hr = MFInitAttributesFromBlob(dest, buffer, size);
3957 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3959 /* Previous items are cleared. */
3960 hr = IMFAttributes_GetCount(dest, &count);
3961 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
3962 ok(count == 0, "Unexpected count %u.\n", count);
3964 heap_free(buffer);
3966 /* Set some attributes of various types. */
3967 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
3968 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
3969 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
3970 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
3971 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
3972 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
3973 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
3975 hr = MFGetAttributesAsBlobSize(attributes, &size);
3976 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
3977 ok(size > 8, "Got unexpected size %u.\n", size);
3979 buffer = heap_alloc(size);
3980 hr = MFGetAttributesAsBlob(attributes, buffer, size);
3981 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
3982 hr = MFInitAttributesFromBlob(dest, buffer, size);
3983 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
3984 heap_free(buffer);
3986 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
3987 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
3988 ok(value32 == 456, "Unexpected value %u.\n", value32);
3989 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
3990 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
3991 ok(value64 == 123, "Unexpected value.\n");
3992 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
3993 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
3994 ok(value_dbl == 0.5, "Unexpected value.\n");
3995 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
3996 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3997 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
3998 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
3999 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4000 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4001 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
4002 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4003 CoTaskMemFree(str);
4004 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4005 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
4006 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4007 CoTaskMemFree(buffer);
4009 IMFAttributes_Release(attributes);
4010 IMFAttributes_Release(dest);
4013 static void test_wrapped_media_type(void)
4015 IMFMediaType *mediatype, *mediatype2;
4016 UINT32 count, type;
4017 HRESULT hr;
4018 GUID guid;
4020 hr = MFCreateMediaType(&mediatype);
4021 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4023 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4024 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4026 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4027 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4028 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4029 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4031 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4032 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
4034 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4035 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
4037 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4038 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4039 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4041 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4042 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
4043 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4045 hr = IMFMediaType_GetCount(mediatype2, &count);
4046 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
4047 ok(count == 3, "Unexpected count %u.\n", count);
4049 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4050 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
4051 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4053 IMFMediaType_Release(mediatype);
4055 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4056 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
4058 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4059 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4060 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4062 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4063 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4065 IMFMediaType_Release(mediatype);
4066 IMFMediaType_Release(mediatype2);
4069 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4071 WAVEFORMATEXTENSIBLE *format_ext;
4072 IMFMediaType *mediatype;
4073 WAVEFORMATEX *format;
4074 UINT32 size;
4075 HRESULT hr;
4077 hr = MFCreateMediaType(&mediatype);
4078 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4080 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4081 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4083 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4084 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4086 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4087 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4089 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4090 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4092 /* Audio/PCM */
4093 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4094 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4095 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4096 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4098 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4099 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4100 ok(format != NULL, "Expected format structure.\n");
4101 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4102 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
4103 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4104 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
4105 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
4106 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4107 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4108 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4109 CoTaskMemFree(format);
4111 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4112 MFWaveFormatExConvertFlag_ForceExtensible);
4113 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4114 ok(format_ext != NULL, "Expected format structure.\n");
4115 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4116 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4117 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4118 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
4119 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
4120 format_ext->Format.nAvgBytesPerSec);
4121 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4122 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4123 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4124 format_ext->Format.cbSize);
4125 CoTaskMemFree(format_ext);
4127 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4128 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4129 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4130 CoTaskMemFree(format);
4132 IMFMediaType_Release(mediatype);
4135 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4137 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4138 IMFByteStream *stream;
4139 IUnknown *object;
4140 HRESULT hr;
4142 ok(!!result, "Unexpected result object.\n");
4144 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4146 hr = IMFAsyncResult_GetObject(result, &object);
4147 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4149 hr = MFEndCreateFile(result, &stream);
4150 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
4151 IMFByteStream_Release(stream);
4153 SetEvent(callback->event);
4155 return S_OK;
4158 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4160 testcallback_QueryInterface,
4161 testcallback_AddRef,
4162 testcallback_Release,
4163 testcallback_GetParameters,
4164 test_create_file_callback_Invoke,
4167 static void test_async_create_file(void)
4169 struct test_callback callback = { { &test_create_file_callback_vtbl } };
4170 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4171 IUnknown *cancel_cookie;
4172 HRESULT hr;
4173 BOOL ret;
4175 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4176 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
4178 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
4180 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4181 GetTempFileNameW(pathW, NULL, 0, fileW);
4183 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4184 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
4185 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
4186 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4188 WaitForSingleObject(callback.event, INFINITE);
4190 IUnknown_Release(cancel_cookie);
4192 CloseHandle(callback.event);
4194 hr = MFShutdown();
4195 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4197 ret = DeleteFileW(fileW);
4198 ok(ret, "Failed to delete test file.\n");
4201 struct activate_object
4203 IMFActivate IMFActivate_iface;
4204 LONG refcount;
4207 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4209 if (IsEqualIID(riid, &IID_IMFActivate) ||
4210 IsEqualIID(riid, &IID_IMFAttributes) ||
4211 IsEqualIID(riid, &IID_IUnknown))
4213 *obj = iface;
4214 IMFActivate_AddRef(iface);
4215 return S_OK;
4218 *obj = NULL;
4219 return E_NOINTERFACE;
4222 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4224 return 2;
4227 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4229 return 1;
4232 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4234 return E_NOTIMPL;
4237 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4239 return E_NOTIMPL;
4242 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4244 return E_NOTIMPL;
4247 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4248 BOOL *result)
4250 return E_NOTIMPL;
4253 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4255 return E_NOTIMPL;
4258 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4260 return E_NOTIMPL;
4263 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4265 return E_NOTIMPL;
4268 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4270 return E_NOTIMPL;
4273 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4275 return E_NOTIMPL;
4278 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4279 UINT32 size, UINT32 *length)
4281 return E_NOTIMPL;
4284 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4285 WCHAR **value, UINT32 *length)
4287 return E_NOTIMPL;
4290 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4292 return E_NOTIMPL;
4295 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4296 UINT32 bufsize, UINT32 *blobsize)
4298 return E_NOTIMPL;
4301 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4303 return E_NOTIMPL;
4306 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4308 return E_NOTIMPL;
4311 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4313 return E_NOTIMPL;
4316 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4318 return E_NOTIMPL;
4321 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4323 return E_NOTIMPL;
4326 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4328 return E_NOTIMPL;
4331 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4333 return E_NOTIMPL;
4336 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4338 return E_NOTIMPL;
4341 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4343 return E_NOTIMPL;
4346 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4348 return E_NOTIMPL;
4351 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4353 return E_NOTIMPL;
4356 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4358 return E_NOTIMPL;
4361 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4363 return E_NOTIMPL;
4366 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4368 return E_NOTIMPL;
4371 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4373 return E_NOTIMPL;
4376 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4378 return E_NOTIMPL;
4381 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4383 return E_NOTIMPL;
4386 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4388 return E_NOTIMPL;
4391 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4393 return E_NOTIMPL;
4396 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4398 return E_NOTIMPL;
4401 static const IMFActivateVtbl activate_object_vtbl =
4403 activate_object_QueryInterface,
4404 activate_object_AddRef,
4405 activate_object_Release,
4406 activate_object_GetItem,
4407 activate_object_GetItemType,
4408 activate_object_CompareItem,
4409 activate_object_Compare,
4410 activate_object_GetUINT32,
4411 activate_object_GetUINT64,
4412 activate_object_GetDouble,
4413 activate_object_GetGUID,
4414 activate_object_GetStringLength,
4415 activate_object_GetString,
4416 activate_object_GetAllocatedString,
4417 activate_object_GetBlobSize,
4418 activate_object_GetBlob,
4419 activate_object_GetAllocatedBlob,
4420 activate_object_GetUnknown,
4421 activate_object_SetItem,
4422 activate_object_DeleteItem,
4423 activate_object_DeleteAllItems,
4424 activate_object_SetUINT32,
4425 activate_object_SetUINT64,
4426 activate_object_SetDouble,
4427 activate_object_SetGUID,
4428 activate_object_SetString,
4429 activate_object_SetBlob,
4430 activate_object_SetUnknown,
4431 activate_object_LockStore,
4432 activate_object_UnlockStore,
4433 activate_object_GetCount,
4434 activate_object_GetItemByIndex,
4435 activate_object_CopyAllItems,
4436 activate_object_ActivateObject,
4437 activate_object_ShutdownObject,
4438 activate_object_DetachObject,
4441 static void test_local_handlers(void)
4443 IMFActivate local_activate = { &activate_object_vtbl };
4444 static const WCHAR localW[] = L"local";
4445 HRESULT hr;
4447 if (!pMFRegisterLocalSchemeHandler)
4449 win_skip("Local handlers are not supported.\n");
4450 return;
4453 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4454 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4456 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4457 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4459 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4460 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4462 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4463 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4465 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4466 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4468 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4469 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4471 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4472 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4474 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4475 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4477 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4478 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4480 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4481 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4484 static void test_create_property_store(void)
4486 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4487 IPropertyStore *store, *store2;
4488 PROPVARIANT value = {0};
4489 PROPERTYKEY key;
4490 ULONG refcount;
4491 DWORD count;
4492 HRESULT hr;
4494 hr = CreatePropertyStore(NULL);
4495 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4497 hr = CreatePropertyStore(&store);
4498 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4500 hr = CreatePropertyStore(&store2);
4501 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4502 ok(store2 != store, "Expected different store objects.\n");
4503 IPropertyStore_Release(store2);
4505 check_interface(store, &IID_IPropertyStoreCache, FALSE);
4506 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
4508 hr = IPropertyStore_GetCount(store, NULL);
4509 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4511 count = 0xdeadbeef;
4512 hr = IPropertyStore_GetCount(store, &count);
4513 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4514 ok(!count, "Unexpected count %u.\n", count);
4516 hr = IPropertyStore_Commit(store);
4517 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4519 hr = IPropertyStore_GetAt(store, 0, &key);
4520 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4522 hr = IPropertyStore_GetValue(store, NULL, &value);
4523 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4525 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
4526 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4528 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4529 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4531 memset(&value, 0, sizeof(PROPVARIANT));
4532 value.vt = VT_I4;
4533 value.lVal = 0xdeadbeef;
4534 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4535 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4537 if (0)
4539 /* crashes on Windows */
4540 hr = IPropertyStore_SetValue(store, NULL, &value);
4541 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4544 hr = IPropertyStore_GetCount(store, &count);
4545 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4546 ok(count == 1, "Unexpected count %u.\n", count);
4548 hr = IPropertyStore_Commit(store);
4549 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4551 hr = IPropertyStore_GetAt(store, 0, &key);
4552 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4553 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
4555 hr = IPropertyStore_GetAt(store, 1, &key);
4556 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4558 memset(&value, 0xcc, sizeof(PROPVARIANT));
4559 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4560 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4561 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
4562 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
4564 memset(&value, 0, sizeof(PROPVARIANT));
4565 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4566 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4568 hr = IPropertyStore_GetCount(store, &count);
4569 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4570 ok(count == 1, "Unexpected count %u.\n", count);
4572 memset(&value, 0xcc, sizeof(PROPVARIANT));
4573 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4574 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4575 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
4576 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
4578 refcount = IPropertyStore_Release(store);
4579 ok(!refcount, "Unexpected refcount %u.\n", refcount);
4582 struct test_thread_param
4584 IMFDXGIDeviceManager *manager;
4585 HANDLE handle;
4586 BOOL lock;
4589 static DWORD WINAPI test_device_manager_thread(void *arg)
4591 struct test_thread_param *param = arg;
4592 ID3D11Device *device;
4593 HRESULT hr;
4595 if (param->lock)
4597 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
4598 (void **)&device, FALSE);
4599 if (SUCCEEDED(hr))
4600 ID3D11Device_Release(device);
4602 else
4603 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
4605 return hr;
4608 static void test_dxgi_device_manager(void)
4610 IMFDXGIDeviceManager *manager, *manager2;
4611 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
4612 struct test_thread_param param;
4613 HANDLE handle1, handle, thread;
4614 UINT token, token2;
4615 IUnknown *unk;
4616 HRESULT hr;
4618 if (!pMFCreateDXGIDeviceManager)
4620 win_skip("MFCreateDXGIDeviceManager not found.\n");
4621 return;
4624 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
4625 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4627 token = 0;
4628 hr = pMFCreateDXGIDeviceManager(&token, NULL);
4629 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4630 ok(!token, "got wrong token: %u.\n", token);
4632 hr = pMFCreateDXGIDeviceManager(&token, &manager);
4633 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4634 EXPECT_REF(manager, 1);
4635 ok(!!token, "got wrong token: %u.\n", token);
4637 Sleep(50);
4638 token2 = 0;
4639 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
4640 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4641 EXPECT_REF(manager2, 1);
4642 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
4643 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
4644 EXPECT_REF(manager, 1);
4646 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4647 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4649 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4650 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4652 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
4653 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4655 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
4656 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
4657 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4658 EXPECT_REF(d3d11_dev, 1);
4660 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
4661 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4662 EXPECT_REF(d3d11_dev, 1);
4664 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
4665 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4667 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4668 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4669 EXPECT_REF(manager, 1);
4670 EXPECT_REF(d3d11_dev, 2);
4672 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
4673 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4674 EXPECT_REF(manager2, 1);
4675 EXPECT_REF(d3d11_dev, 2);
4677 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4678 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4679 EXPECT_REF(manager, 1);
4680 EXPECT_REF(d3d11_dev, 2);
4682 /* GetVideoService() on device change. */
4683 handle = NULL;
4684 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4685 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4686 ok(!!handle, "Unexpected handle value %p.\n", handle);
4688 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
4689 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
4690 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4691 EXPECT_REF(d3d11_dev2, 1);
4692 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
4693 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4694 EXPECT_REF(manager, 1);
4695 EXPECT_REF(d3d11_dev2, 2);
4696 EXPECT_REF(d3d11_dev, 1);
4698 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4699 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr);
4701 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4702 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4704 handle = NULL;
4705 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4706 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4707 ok(!!handle, "Unexpected handle value %p.\n", handle);
4709 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4710 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4712 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4713 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4714 IUnknown_Release(unk);
4716 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
4717 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4718 IUnknown_Release(unk);
4720 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
4721 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4722 IUnknown_Release(unk);
4724 handle1 = NULL;
4725 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4726 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4727 ok(handle != handle1, "Unexpected handle.\n");
4729 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4730 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4732 /* Already closed. */
4733 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4734 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4736 handle = NULL;
4737 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4738 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4740 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4741 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4743 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
4744 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4746 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4747 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4748 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
4749 ID3D11Device_Release(device);
4751 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4752 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4754 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4755 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4757 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
4758 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4760 /* Locked with one handle, unlock with another. */
4761 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4762 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4764 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4765 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4767 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4768 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4770 ID3D11Device_Release(device);
4772 /* Closing unlocks the device. */
4773 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4774 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4776 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4777 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4778 ID3D11Device_Release(device);
4780 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4781 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4783 /* Open two handles. */
4784 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4785 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4787 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4788 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4790 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4791 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4792 ID3D11Device_Release(device);
4794 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4795 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4796 ID3D11Device_Release(device);
4798 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4799 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4801 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4802 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4804 param.manager = manager;
4805 param.handle = handle;
4806 param.lock = TRUE;
4807 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4808 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4809 GetExitCodeThread(thread, (DWORD *)&hr);
4810 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#x.\n", hr);
4811 CloseHandle(thread);
4813 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4814 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4816 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4817 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4819 /* Lock on main thread, unlock on another. */
4820 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4822 ID3D11Device_Release(device);
4824 param.manager = manager;
4825 param.handle = handle;
4826 param.lock = FALSE;
4827 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4828 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4829 GetExitCodeThread(thread, (DWORD *)&hr);
4830 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4831 CloseHandle(thread);
4833 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4834 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4836 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4837 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4839 IMFDXGIDeviceManager_Release(manager);
4840 EXPECT_REF(d3d11_dev2, 1);
4841 ID3D11Device_Release(d3d11_dev);
4842 ID3D11Device_Release(d3d11_dev2);
4843 IMFDXGIDeviceManager_Release(manager2);
4846 static void test_MFCreateTransformActivate(void)
4848 IMFActivate *activate;
4849 UINT32 count;
4850 HRESULT hr;
4852 if (!pMFCreateTransformActivate)
4854 win_skip("MFCreateTransformActivate() is not available.\n");
4855 return;
4858 hr = pMFCreateTransformActivate(&activate);
4859 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
4861 hr = IMFActivate_GetCount(activate, &count);
4862 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4863 ok(!count, "Unexpected attribute count %u.\n", count);
4865 IMFActivate_Release(activate);
4868 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
4870 if (IsEqualIID(riid, &IID_IClassFactory) ||
4871 IsEqualIID(riid, &IID_IUnknown))
4873 *obj = iface;
4874 IClassFactory_AddRef(iface);
4875 return S_OK;
4878 *obj = NULL;
4879 return E_NOINTERFACE;
4882 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
4884 return 2;
4887 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
4889 return 1;
4892 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
4894 ok(0, "Unexpected call.\n");
4895 return E_NOTIMPL;
4898 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
4900 return S_OK;
4903 static const IClassFactoryVtbl test_mft_factory_vtbl =
4905 test_mft_factory_QueryInterface,
4906 test_mft_factory_AddRef,
4907 test_mft_factory_Release,
4908 test_mft_factory_CreateInstance,
4909 test_mft_factory_LockServer,
4912 static void test_MFTRegisterLocal(void)
4914 IClassFactory test_factory = { &test_mft_factory_vtbl };
4915 MFT_REGISTER_TYPE_INFO input_types[1];
4916 IMFActivate **activate;
4917 UINT32 count, count2;
4918 HRESULT hr;
4920 if (!pMFTRegisterLocal)
4922 win_skip("MFTRegisterLocal() is not available.\n");
4923 return;
4926 input_types[0].guidMajorType = MFMediaType_Audio;
4927 input_types[0].guidSubtype = MFAudioFormat_PCM;
4928 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
4929 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4931 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
4932 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4934 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
4935 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4936 ok(count > 0, "Unexpected count %u.\n", count);
4937 CoTaskMemFree(activate);
4939 hr = pMFTUnregisterLocal(&test_factory);
4940 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
4942 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
4943 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4944 ok(count2 < count, "Unexpected count %u.\n", count2);
4945 CoTaskMemFree(activate);
4947 hr = pMFTUnregisterLocal(&test_factory);
4948 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
4950 hr = pMFTUnregisterLocal(NULL);
4951 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4953 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
4954 0, NULL);
4955 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4957 hr = pMFTUnregisterLocal(NULL);
4958 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4960 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
4961 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
4963 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
4964 0, NULL);
4965 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
4967 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
4968 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4971 static void test_queue_com(void)
4973 static int system_queues[] =
4975 MFASYNC_CALLBACK_QUEUE_STANDARD,
4976 MFASYNC_CALLBACK_QUEUE_RT,
4977 MFASYNC_CALLBACK_QUEUE_IO,
4978 MFASYNC_CALLBACK_QUEUE_TIMER,
4979 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
4980 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
4983 static int user_queues[] =
4985 MF_STANDARD_WORKQUEUE,
4986 MF_WINDOW_WORKQUEUE,
4987 MF_MULTITHREADED_WORKQUEUE,
4990 char path_name[MAX_PATH];
4991 PROCESS_INFORMATION info;
4992 STARTUPINFOA startup;
4993 char **argv;
4994 int i;
4996 if (!pCoGetApartmentType)
4998 win_skip("CoGetApartmentType() is not available.\n");
4999 return;
5002 winetest_get_mainargs(&argv);
5004 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5006 memset(&startup, 0, sizeof(startup));
5007 startup.cb = sizeof(startup);
5008 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5009 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5010 "CreateProcess failed.\n" );
5011 wait_child_process(info.hProcess);
5012 CloseHandle(info.hProcess);
5013 CloseHandle(info.hThread);
5016 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5018 memset(&startup, 0, sizeof(startup));
5019 startup.cb = sizeof(startup);
5020 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5021 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5022 "CreateProcess failed.\n" );
5023 wait_child_process(info.hProcess);
5024 CloseHandle(info.hProcess);
5025 CloseHandle(info.hThread);
5029 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5031 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5032 APTTYPEQUALIFIER qualifier;
5033 APTTYPE com_type;
5034 HRESULT hr;
5036 hr = pCoGetApartmentType(&com_type, &qualifier);
5037 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr);
5038 if (SUCCEEDED(hr))
5040 todo_wine {
5041 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5042 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5043 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5044 else
5045 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5046 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5050 SetEvent(callback->event);
5051 return S_OK;
5054 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5056 testcallback_QueryInterface,
5057 testcallback_AddRef,
5058 testcallback_Release,
5059 testcallback_GetParameters,
5060 test_queue_com_state_callback_Invoke,
5063 static void test_queue_com_state(const char *name)
5065 struct test_callback callback = { { &test_queue_com_state_callback_vtbl } };
5066 DWORD queue, queue_type;
5067 HRESULT hr;
5069 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
5071 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5072 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
5074 if (name[0] == 's')
5076 callback.param = name[1] - '0';
5077 hr = MFPutWorkItem(callback.param, &callback.IMFAsyncCallback_iface, NULL);
5078 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5079 WaitForSingleObject(callback.event, INFINITE);
5081 else if (name[0] == 'u')
5083 queue_type = name[1] - '0';
5085 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5086 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5087 "Failed to allocate a queue of type %u, hr %#x.\n", queue_type, hr);
5089 if (SUCCEEDED(hr))
5091 callback.param = queue;
5092 hr = MFPutWorkItem(queue, &callback.IMFAsyncCallback_iface, NULL);
5093 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5094 WaitForSingleObject(callback.event, INFINITE);
5096 hr = MFUnlockWorkQueue(queue);
5097 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
5101 CloseHandle(callback.event);
5103 hr = MFShutdown();
5104 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
5107 static void test_MFGetStrideForBitmapInfoHeader(void)
5109 static const struct stride_test
5111 const GUID *subtype;
5112 unsigned int width;
5113 LONG stride;
5115 stride_tests[] =
5117 { &MFVideoFormat_RGB8, 3, -4 },
5118 { &MFVideoFormat_RGB8, 1, -4 },
5119 { &MFVideoFormat_RGB555, 3, -8 },
5120 { &MFVideoFormat_RGB555, 1, -4 },
5121 { &MFVideoFormat_RGB565, 3, -8 },
5122 { &MFVideoFormat_RGB565, 1, -4 },
5123 { &MFVideoFormat_RGB24, 3, -12 },
5124 { &MFVideoFormat_RGB24, 1, -4 },
5125 { &MFVideoFormat_RGB32, 3, -12 },
5126 { &MFVideoFormat_RGB32, 1, -4 },
5127 { &MFVideoFormat_ARGB32, 3, -12 },
5128 { &MFVideoFormat_ARGB32, 1, -4 },
5129 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5130 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5131 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5132 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5134 /* YUV */
5135 { &MFVideoFormat_NV12, 1, 1 },
5136 { &MFVideoFormat_NV12, 2, 2 },
5137 { &MFVideoFormat_NV12, 3, 3 },
5138 { &MFVideoFormat_AYUV, 1, 4 },
5139 { &MFVideoFormat_AYUV, 4, 16 },
5140 { &MFVideoFormat_AYUV, 5, 20 },
5141 { &MFVideoFormat_IMC1, 1, 4 },
5142 { &MFVideoFormat_IMC1, 2, 4 },
5143 { &MFVideoFormat_IMC1, 3, 8 },
5144 { &MFVideoFormat_IMC3, 1, 4 },
5145 { &MFVideoFormat_IMC3, 2, 4 },
5146 { &MFVideoFormat_IMC3, 3, 8 },
5147 { &MFVideoFormat_IMC2, 1, 1 },
5148 { &MFVideoFormat_IMC2, 2, 2 },
5149 { &MFVideoFormat_IMC2, 3, 3 },
5150 { &MFVideoFormat_IMC4, 1, 1 },
5151 { &MFVideoFormat_IMC4, 2, 2 },
5152 { &MFVideoFormat_IMC4, 3, 3 },
5153 { &MFVideoFormat_YV12, 1, 1 },
5154 { &MFVideoFormat_YV12, 2, 2 },
5155 { &MFVideoFormat_YV12, 3, 3 },
5156 { &MFVideoFormat_YV12, 320, 320 },
5157 { &MFVideoFormat_I420, 1, 1 },
5158 { &MFVideoFormat_I420, 2, 2 },
5159 { &MFVideoFormat_I420, 3, 3 },
5160 { &MFVideoFormat_I420, 320, 320 },
5162 unsigned int i;
5163 LONG stride;
5164 HRESULT hr;
5166 if (!pMFGetStrideForBitmapInfoHeader)
5168 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5169 return;
5172 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5173 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5175 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5177 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5178 ok(hr == S_OK, "%u: failed to get stride, hr %#x.\n", i, hr);
5179 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %d, expected %d.\n", i,
5180 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5184 static void test_MFCreate2DMediaBuffer(void)
5186 static const struct _2d_buffer_test
5188 unsigned int width;
5189 unsigned int height;
5190 unsigned int fourcc;
5191 unsigned int contiguous_length;
5192 int pitch;
5193 unsigned int plane_multiplier;
5194 } _2d_buffer_tests[] =
5196 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64 },
5197 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5198 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5199 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5201 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128 },
5202 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5203 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5204 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5205 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5206 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5208 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128, 2 },
5209 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128, 2 },
5210 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 2 },
5211 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128, 2 },
5213 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128, 2 },
5214 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128, 2 },
5215 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 2 },
5216 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128, 2 },
5218 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5219 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5220 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128 },
5222 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5223 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5224 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64 },
5226 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5227 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5228 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64 },
5230 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5231 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5232 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64 },
5234 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5235 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5236 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5238 unsigned int max_length, length, length2;
5239 BYTE *buffer_start, *data, *data2;
5240 IMF2DBuffer2 *_2dbuffer2;
5241 IMF2DBuffer *_2dbuffer;
5242 IMFMediaBuffer *buffer;
5243 int i, pitch, pitch2;
5244 HRESULT hr;
5245 BOOL ret;
5247 if (!pMFCreate2DMediaBuffer)
5249 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5250 return;
5253 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5254 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5256 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5257 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5259 /* YUV formats can't be bottom-up. */
5260 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5261 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5263 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5264 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5266 check_interface(buffer, &IID_IMFGetService, TRUE);
5267 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5269 /* Full backing buffer size, with 64 bytes per row alignment. */
5270 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5271 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5272 ok(max_length > 0, "Unexpected length %u.\n", max_length);
5274 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5275 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5276 ok(!length, "Unexpected length.\n");
5278 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5279 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
5281 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5282 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5283 ok(length == 10, "Unexpected length.\n");
5285 /* Linear lock/unlock. */
5287 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5288 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5290 /* Linear locking call returns plane size.*/
5291 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5292 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5293 ok(max_length == length, "Unexpected length.\n");
5295 length = 0;
5296 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5297 ok(max_length == length && length == 9, "Unexpected length %u.\n", length);
5299 /* Already locked */
5300 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5301 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5302 ok(data2 == data, "Unexpected pointer.\n");
5304 hr = IMFMediaBuffer_Unlock(buffer);
5305 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5307 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5308 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5310 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5311 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5313 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5314 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5315 ok(length == 9, "Unexpected length %u.\n", length);
5317 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5318 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5320 /* 2D lock. */
5321 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5322 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
5324 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5325 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5327 hr = IMFMediaBuffer_Unlock(buffer);
5328 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5330 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5331 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5333 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5334 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5336 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5337 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5339 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5340 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5342 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5343 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5344 ok(!!data, "Expected data pointer.\n");
5345 ok(pitch == 64, "Unexpected pitch %d.\n", pitch);
5347 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5348 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5349 ok(data == data2, "Expected data pointer.\n");
5351 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5352 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5354 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5355 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5357 /* Active 2D lock */
5358 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5359 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5361 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5362 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5364 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5365 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5367 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5368 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5370 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5371 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5373 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5374 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#x.\n", hr);
5376 if (SUCCEEDED(hr))
5378 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5379 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5381 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5382 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5384 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5385 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5387 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5388 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5390 /* Flags are ignored. */
5391 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5392 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5394 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5395 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5397 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5398 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5400 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5401 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5403 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5404 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5406 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5407 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5409 IMF2DBuffer2_Release(_2dbuffer2);
5411 else
5412 win_skip("IMF2DBuffer2 is not supported.\n");
5414 IMF2DBuffer_Release(_2dbuffer);
5416 IMFMediaBuffer_Release(buffer);
5418 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5420 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5422 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5423 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5425 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5426 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5428 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5429 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5430 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %u for %u x %u, format %s.\n",
5431 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5433 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5434 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5435 ok(length == ptr->contiguous_length, "%d: unexpected linear buffer length %u for %u x %u, format %s.\n",
5436 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5438 hr = IMFMediaBuffer_Unlock(buffer);
5439 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5441 hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2);
5442 ok(hr == S_OK, "Failed to get plane size, hr %#x.\n", hr);
5443 if (ptr->plane_multiplier)
5444 length2 *= ptr->plane_multiplier;
5445 ok(length2 == length, "%d: contiguous length %u does not match plane size %u, %u x %u, format %s.\n", i, length,
5446 length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5448 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5449 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5451 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
5452 ok(hr == S_OK, "Failed to get scanline, hr %#x.\n", hr);
5453 ok(data2 == data, "Unexpected data pointer.\n");
5454 ok(pitch == pitch2, "Unexpected pitch.\n");
5456 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5457 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5459 ok(pitch == ptr->pitch, "%d: unexpected pitch %d, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
5460 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5462 ret = TRUE;
5463 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
5464 ok(hr == S_OK, "Failed to get format flag, hr %#x.\n", hr);
5465 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
5467 IMF2DBuffer_Release(_2dbuffer);
5469 IMFMediaBuffer_Release(buffer);
5473 static void test_MFCreateMediaBufferFromMediaType(void)
5475 static struct audio_buffer_test
5477 unsigned int duration;
5478 unsigned int min_length;
5479 unsigned int min_alignment;
5480 unsigned int block_alignment;
5481 unsigned int bytes_per_second;
5482 unsigned int buffer_length;
5483 } audio_tests[] =
5485 { 0, 0, 0, 4, 0, 20 },
5486 { 0, 16, 0, 4, 0, 20 },
5487 { 0, 0, 32, 4, 0, 36 },
5488 { 0, 64, 32, 4, 0, 64 },
5489 { 1, 0, 0, 4, 16, 36 },
5490 { 2, 0, 0, 4, 16, 52 },
5492 IMFMediaBuffer *buffer;
5493 UINT32 length;
5494 HRESULT hr;
5495 IMFMediaType *media_type;
5496 unsigned int i;
5498 if (!pMFCreateMediaBufferFromMediaType)
5500 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
5501 return;
5504 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
5505 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5507 hr = MFCreateMediaType(&media_type);
5508 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5510 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
5511 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5513 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
5515 const struct audio_buffer_test *ptr = &audio_tests[i];
5517 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
5518 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5520 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
5521 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5523 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
5524 ptr->min_alignment, &buffer);
5525 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr);
5526 if (FAILED(hr))
5527 break;
5529 check_interface(buffer, &IID_IMFGetService, FALSE);
5531 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5532 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5533 ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
5535 IMFMediaBuffer_Release(buffer);
5538 IMFMediaType_Release(media_type);
5541 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
5543 GUID guid, subtype;
5544 UINT32 value;
5545 HRESULT hr;
5547 hr = IMFMediaType_GetMajorType(mediatype, &guid);
5548 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
5549 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
5551 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
5552 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
5554 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
5556 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
5557 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5559 if (fex->dwChannelMask)
5561 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
5562 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5563 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
5566 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
5568 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
5569 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5570 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
5573 else
5575 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
5576 subtype.Data1 = format->wFormatTag;
5577 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5579 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
5580 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5581 ok(value, "Unexpected value.\n");
5584 if (format->nChannels)
5586 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
5587 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5588 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
5591 if (format->nSamplesPerSec)
5593 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
5594 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5595 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
5598 if (format->nAvgBytesPerSec)
5600 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
5601 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5602 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
5605 if (format->nBlockAlign)
5607 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
5608 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5609 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
5612 if (format->wBitsPerSample)
5614 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
5615 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5616 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
5619 /* Only set for uncompressed formats. */
5620 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
5621 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
5622 IsEqualGUID(&guid, &MFAudioFormat_PCM))
5624 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5625 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
5627 else
5628 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
5631 static void test_MFInitMediaTypeFromWaveFormatEx(void)
5633 static const WAVEFORMATEX waveformatex_tests[] =
5635 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
5636 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
5637 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
5638 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
5639 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
5640 { 1234, 0, 0, 0, 0, 0 },
5641 { WAVE_FORMAT_ALAW },
5642 { WAVE_FORMAT_CREATIVE_ADPCM },
5643 { WAVE_FORMAT_MPEGLAYER3 },
5644 { WAVE_FORMAT_MPEG_ADTS_AAC },
5645 { WAVE_FORMAT_ALAC },
5646 { WAVE_FORMAT_AMR_NB },
5647 { WAVE_FORMAT_AMR_WB },
5648 { WAVE_FORMAT_AMR_WP },
5649 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
5650 { WAVE_FORMAT_DRM },
5651 { WAVE_FORMAT_DTS },
5652 { WAVE_FORMAT_FLAC },
5653 { WAVE_FORMAT_MPEG },
5654 { WAVE_FORMAT_WMAVOICE9 },
5655 { WAVE_FORMAT_OPUS },
5656 { WAVE_FORMAT_WMAUDIO2 },
5657 { WAVE_FORMAT_WMAUDIO3 },
5658 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
5659 { WAVE_FORMAT_WMASPDIF },
5662 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
5663 WAVEFORMATEXTENSIBLE waveformatext;
5664 MPEGLAYER3WAVEFORMAT mp3format;
5665 IMFMediaType *mediatype;
5666 unsigned int i, size;
5667 HRESULT hr;
5669 hr = MFCreateMediaType(&mediatype);
5670 ok(hr == S_OK, "Failed to create mediatype, hr %#x.\n", hr);
5672 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
5674 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
5675 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#x.\n", i, waveformatex_tests[i].wFormatTag, hr);
5677 validate_media_type(mediatype, &waveformatex_tests[i]);
5679 waveformatext.Format = waveformatex_tests[i];
5680 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
5681 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
5682 waveformatext.Samples.wSamplesPerBlock = 123;
5683 waveformatext.dwChannelMask = 0x8;
5684 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
5685 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
5687 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
5688 ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr);
5690 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
5691 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
5693 validate_media_type(mediatype, &waveformatext.Format);
5696 /* MPEGLAYER3WAVEFORMAT */
5697 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
5698 mp3format.wfx.nChannels = 2;
5699 mp3format.wfx.nSamplesPerSec = 44100;
5700 mp3format.wfx.nAvgBytesPerSec = 16000;
5701 mp3format.wfx.nBlockAlign = 1;
5702 mp3format.wfx.wBitsPerSample = 0;
5703 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
5704 mp3format.wID = MPEGLAYER3_ID_MPEG;
5705 mp3format.fdwFlags = 0;
5706 mp3format.nBlockSize = 417;
5707 mp3format.nFramesPerBlock = 0;
5708 mp3format.nCodecDelay = 0;
5710 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
5711 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5713 validate_media_type(mediatype, &mp3format.wfx);
5714 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
5715 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5716 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
5717 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
5719 IMFMediaType_Release(mediatype);
5722 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
5724 MFVIDEOFORMAT *video_format;
5725 IMFMediaType *media_type;
5726 UINT32 size;
5727 HRESULT hr;
5729 hr = MFCreateMediaType(&media_type);
5730 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5732 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
5733 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5734 ok(!!video_format, "Unexpected format.\n");
5735 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
5736 CoTaskMemFree(video_format);
5738 IMFMediaType_Release(media_type);
5741 static void test_MFCreateDXSurfaceBuffer(void)
5743 IDirect3DSurface9 *backbuffer = NULL, *surface;
5744 IDirect3DSwapChain9 *swapchain;
5745 IDirect3DDevice9 *device;
5746 IMF2DBuffer2 *_2dbuffer2;
5747 IMFMediaBuffer *buffer;
5748 IMF2DBuffer *_2dbuffer;
5749 BYTE *data, *data2;
5750 IMFGetService *gs;
5751 IDirect3D9 *d3d;
5752 DWORD length;
5753 HWND window;
5754 HRESULT hr;
5755 LONG pitch;
5756 BOOL value;
5758 if (!pMFCreateDXSurfaceBuffer)
5760 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
5761 return;
5764 window = create_window();
5765 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5766 ok(!!d3d, "Failed to create a D3D object.\n");
5767 if (!(device = create_device(d3d, window)))
5769 skip("Failed to create a D3D device, skipping tests.\n");
5770 goto done;
5773 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
5774 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
5776 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5777 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
5778 ok(backbuffer != NULL, "The back buffer is NULL\n");
5780 IDirect3DSwapChain9_Release(swapchain);
5782 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
5783 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5785 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
5786 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5788 /* Surface is accessible. */
5789 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
5790 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5791 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
5792 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5793 ok(surface == backbuffer, "Unexpected surface pointer.\n");
5794 IDirect3DSurface9_Release(surface);
5795 IMFGetService_Release(gs);
5797 length = 0;
5798 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5799 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5800 ok(!!length, "Unexpected length %u.\n", length);
5802 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5803 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5804 ok(!length, "Unexpected length %u.\n", length);
5806 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5807 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5809 /* Unlock twice. */
5810 hr = IMFMediaBuffer_Unlock(buffer);
5811 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5813 hr = IMFMediaBuffer_Unlock(buffer);
5814 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5816 /* Lock twice. */
5817 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5818 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5820 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5822 ok(data == data2, "Unexpected pointer.\n");
5824 hr = IMFMediaBuffer_Unlock(buffer);
5825 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5827 hr = IMFMediaBuffer_Unlock(buffer);
5828 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5830 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5831 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5833 /* Unlocked. */
5834 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5835 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5837 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5838 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5840 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5841 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5843 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5844 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5846 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5847 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5849 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5850 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5852 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5853 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5855 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5856 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5858 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
5859 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5860 ok(!value, "Unexpected return value %d.\n", value);
5862 IMF2DBuffer_Release(_2dbuffer);
5864 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5865 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5867 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
5868 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5869 ok(data == data2, "Unexpected scanline pointer.\n");
5870 memset(data, 0xab, 4);
5871 IMF2DBuffer2_Unlock2D(_2dbuffer2);
5873 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
5874 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5875 ok(data[0] == 0xab, "Unexpected leading byte.\n");
5876 IMF2DBuffer2_Unlock2D(_2dbuffer2);
5878 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5880 ok(data[0] == 0xab, "Unexpected leading byte.\n");
5881 hr = IMFMediaBuffer_Unlock(buffer);
5882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5884 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
5885 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5886 IMF2DBuffer2_Unlock2D(_2dbuffer2);
5888 IMF2DBuffer2_Release(_2dbuffer2);
5890 IMFMediaBuffer_Release(buffer);
5892 done:
5893 if (backbuffer)
5894 IDirect3DSurface9_Release(backbuffer);
5895 IDirect3D9_Release(d3d);
5896 DestroyWindow(window);
5899 static void test_MFCreateTrackedSample(void)
5901 IMFTrackedSample *tracked_sample;
5902 IMFSample *sample;
5903 IUnknown *unk;
5904 HRESULT hr;
5906 if (!pMFCreateTrackedSample)
5908 win_skip("MFCreateTrackedSample() is not available.\n");
5909 return;
5912 hr = pMFCreateTrackedSample(&tracked_sample);
5913 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5915 /* It's actually a sample. */
5916 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
5917 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5919 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
5920 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5921 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
5922 IUnknown_Release(unk);
5924 IMFSample_Release(sample);
5926 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
5928 IMFTrackedSample_Release(tracked_sample);
5931 static void test_MFFrameRateToAverageTimePerFrame(void)
5933 static const struct frame_rate_test
5935 unsigned int numerator;
5936 unsigned int denominator;
5937 UINT64 avgtime;
5938 } frame_rate_tests[] =
5940 { 60000, 1001, 166833 },
5941 { 30000, 1001, 333667 },
5942 { 24000, 1001, 417188 },
5943 { 60, 1, 166667 },
5944 { 30, 1, 333333 },
5945 { 50, 1, 200000 },
5946 { 25, 1, 400000 },
5947 { 24, 1, 416667 },
5949 { 39, 1, 256410 },
5950 { 120, 1, 83333 },
5952 unsigned int i;
5953 UINT64 avgtime;
5954 HRESULT hr;
5956 avgtime = 1;
5957 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
5958 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5959 ok(!avgtime, "Unexpected frame time.\n");
5961 avgtime = 1;
5962 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
5963 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5964 ok(!avgtime, "Unexpected frame time.\n");
5966 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
5968 avgtime = 0;
5969 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
5970 frame_rate_tests[i].denominator, &avgtime);
5971 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5972 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
5973 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
5977 static void test_MFMapDXGIFormatToDX9Format(void)
5979 static const struct format_pair
5981 DXGI_FORMAT dxgi_format;
5982 DWORD d3d9_format;
5984 formats_map[] =
5986 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
5987 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
5988 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
5989 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
5990 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
5991 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
5992 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
5993 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
5994 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
5995 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
5996 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
5997 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
5998 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
5999 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6000 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6001 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6002 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6003 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6004 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6005 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6006 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6007 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6008 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6009 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6010 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6011 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6012 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6013 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6014 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6015 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6016 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6017 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6018 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6019 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6020 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6021 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6022 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6023 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6024 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6025 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6026 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6027 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6028 { DXGI_FORMAT_P8, D3DFMT_P8 },
6029 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6031 unsigned int i;
6032 DWORD format;
6034 if (!pMFMapDXGIFormatToDX9Format)
6036 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6037 return;
6040 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6042 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6043 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#x, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6047 static void test_MFMapDX9FormatToDXGIFormat(void)
6049 static const struct format_pair
6051 DXGI_FORMAT dxgi_format;
6052 DWORD d3d9_format;
6054 formats_map[] =
6056 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6057 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6058 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6059 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6060 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6061 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6062 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6063 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6064 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6065 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6066 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6067 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6068 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6069 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6070 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6071 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6072 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6073 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6074 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6075 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6076 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6077 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6078 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6079 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6080 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6081 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6082 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6083 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6084 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6085 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6086 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6087 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6088 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6089 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6090 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6091 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6092 { DXGI_FORMAT_P8, D3DFMT_P8 },
6093 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6095 DXGI_FORMAT format;
6096 unsigned int i;
6098 if (!pMFMapDX9FormatToDXGIFormat)
6100 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6101 return;
6104 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6106 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6107 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#x.\n",
6108 format, formats_map[i].d3d9_format);
6112 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6113 REFIID riid, void **obj)
6115 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6116 IsEqualIID(riid, &IID_IUnknown))
6118 *obj = iface;
6119 IMFVideoSampleAllocatorNotify_AddRef(iface);
6120 return S_OK;
6123 *obj = NULL;
6124 return E_NOINTERFACE;
6127 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6129 return 2;
6132 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6134 return 1;
6137 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6139 return E_NOTIMPL;
6142 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6144 test_notify_callback_QueryInterface,
6145 test_notify_callback_AddRef,
6146 test_notify_callback_Release,
6147 test_notify_callback_NotifyRelease,
6150 static IMFMediaType * create_video_type(const GUID *subtype)
6152 IMFMediaType *video_type;
6153 HRESULT hr;
6155 hr = MFCreateMediaType(&video_type);
6156 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6158 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6159 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6161 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6162 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6164 return video_type;
6167 static ID3D11Device *create_d3d11_device(void)
6169 static const D3D_FEATURE_LEVEL default_feature_level[] =
6171 D3D_FEATURE_LEVEL_11_0,
6172 D3D_FEATURE_LEVEL_10_1,
6173 D3D_FEATURE_LEVEL_10_0,
6175 const D3D_FEATURE_LEVEL *feature_level;
6176 unsigned int feature_level_count;
6177 ID3D11Device *device;
6179 feature_level = default_feature_level;
6180 feature_level_count = ARRAY_SIZE(default_feature_level);
6182 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6183 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6184 return device;
6185 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6186 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6187 return device;
6188 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6189 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6190 return device;
6192 return NULL;
6195 static void test_dxgi_surface_buffer(void)
6197 IMFDXGIBuffer *dxgi_buffer;
6198 D3D11_TEXTURE2D_DESC desc;
6199 ID3D11Texture2D *texture;
6200 IMFMediaBuffer *buffer;
6201 ID3D11Device *device;
6202 UINT index, size;
6203 IUnknown *obj;
6204 HRESULT hr;
6205 BYTE *data;
6207 if (!pMFCreateDXGISurfaceBuffer)
6209 skip("MFCreateDXGISurfaceBuffer() is not available.\n");
6210 return;
6213 device = create_d3d11_device();
6215 memset(&desc, 0, sizeof(desc));
6216 desc.Width = 64;
6217 desc.Height = 64;
6218 desc.ArraySize = 1;
6219 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
6220 desc.SampleDesc.Count = 1;
6221 desc.SampleDesc.Quality = 0;
6223 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6224 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6226 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
6227 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6229 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6230 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6231 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6232 check_interface(buffer, &IID_IMFGetService, FALSE);
6234 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6235 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6237 EXPECT_REF(texture, 2);
6238 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
6239 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6240 EXPECT_REF(texture, 3);
6241 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
6242 IUnknown_Release(obj);
6244 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
6245 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6247 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
6248 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6249 ok(index == 0, "Unexpected subresource index.\n");
6251 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6252 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6254 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
6255 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6257 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
6258 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6259 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
6260 IUnknown_Release(obj);
6262 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6263 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6265 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
6266 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6268 IMFDXGIBuffer_Release(dxgi_buffer);
6270 IMFMediaBuffer_Release(buffer);
6272 ID3D11Texture2D_Release(texture);
6274 ID3D11Device_Release(device);
6277 static void test_sample_allocator(void)
6279 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
6280 IMFVideoSampleAllocatorCallback *allocator_cb;
6281 IMFVideoSampleAllocatorEx *allocatorex;
6282 IMFMediaType *media_type, *video_type;
6283 IMFVideoSampleAllocator *allocator;
6284 IMFDXGIDeviceManager *manager;
6285 IMFSample *sample, *sample2;
6286 IMFDXGIBuffer *dxgi_buffer;
6287 D3D11_TEXTURE2D_DESC desc;
6288 ID3D11Texture2D *texture;
6289 IMFMediaBuffer *buffer;
6290 ID3D11Device *device;
6291 LONG refcount, count;
6292 unsigned int token;
6293 IUnknown *unk;
6294 HRESULT hr;
6295 BYTE *data;
6297 if (!pMFCreateVideoSampleAllocatorEx)
6299 skip("MFCreateVideoSampleAllocatorEx() is not available.\n");
6300 return;
6303 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
6304 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6306 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
6307 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
6308 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
6310 IUnknown_Release(unk);
6312 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6313 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6315 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6318 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6319 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6321 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
6322 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6324 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6325 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6327 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
6328 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6330 count = 10;
6331 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6332 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6333 ok(!count, "Unexpected count %d.\n", count);
6335 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6336 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6338 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6339 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6341 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
6342 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6344 hr = MFCreateMediaType(&media_type);
6345 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6347 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
6348 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6350 video_type = create_video_type(&MFVideoFormat_RGB32);
6352 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6353 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6355 /* Frame size is required. */
6356 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6357 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6359 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6360 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6362 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6363 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6365 count = 0;
6366 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6367 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6368 ok(count == 1, "Unexpected count %d.\n", count);
6370 sample = NULL;
6371 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6372 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6373 refcount = get_refcount(sample);
6375 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6376 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6377 ok(!count, "Unexpected count %d.\n", count);
6379 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
6380 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6382 /* Reinitialize with active sample. */
6383 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6384 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6385 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
6387 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6388 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6389 ok(!count, "Unexpected count %d.\n", count);
6391 check_interface(sample, &IID_IMFTrackedSample, TRUE);
6392 check_interface(sample, &IID_IMFDesiredSample, FALSE);
6394 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6395 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6397 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6398 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6399 check_interface(buffer, &IID_IMFGetService, TRUE);
6400 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
6402 IMFMediaBuffer_Release(buffer);
6403 IMFSample_Release(sample);
6405 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6406 IMFVideoSampleAllocator_Release(allocator);
6408 /* IMFVideoSampleAllocatorEx */
6409 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6410 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6412 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6413 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6415 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
6416 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6418 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
6419 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6421 count = 0;
6422 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6423 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6424 ok(count == 1, "Unexpected count %d.\n", count);
6426 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6427 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6429 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6430 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6432 IMFSample_Release(sample);
6434 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6435 IMFVideoSampleAllocatorEx_Release(allocatorex);
6437 /* Using device manager */
6438 if (!(device = create_d3d11_device()))
6440 skip("Failed to create a D3D11 device, skipping tests.\n");
6441 return;
6444 hr = pMFCreateDXGIDeviceManager(&token, &manager);
6445 ok(hr == S_OK, "Failed to create device manager, hr %#x.\n", hr);
6447 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
6448 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
6450 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6451 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6453 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
6454 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6456 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6457 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6459 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6460 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6462 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6463 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6465 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6466 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6468 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6469 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6470 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6471 check_interface(buffer, &IID_IMFGetService, FALSE);
6473 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6474 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6476 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6477 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6479 ID3D11Texture2D_GetDesc(texture, &desc);
6480 ok(desc.Width == 320, "Unexpected width %u.\n", desc.Width);
6481 ok(desc.Height == 240, "Unexpected height %u.\n", desc.Height);
6482 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
6483 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
6484 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
6485 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
6486 ok(desc.SampleDesc.Quality == 0, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
6487 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
6488 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6489 desc.BindFlags);
6490 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6491 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6493 ID3D11Texture2D_Release(texture);
6494 IMFDXGIBuffer_Release(dxgi_buffer);
6496 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6497 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6499 hr = IMFMediaBuffer_Unlock(buffer);
6500 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6502 IMFSample_Release(sample);
6504 IMFVideoSampleAllocator_Release(allocator);
6506 IMFMediaType_Release(media_type);
6507 IMFDXGIDeviceManager_Release(manager);
6508 ID3D11Device_Release(device);
6511 START_TEST(mfplat)
6513 char **argv;
6514 int argc;
6516 init_functions();
6518 argc = winetest_get_mainargs(&argv);
6519 if (argc >= 3)
6521 test_queue_com_state(argv[2]);
6522 return;
6525 CoInitialize(NULL);
6527 test_startup();
6528 test_register();
6529 test_media_type();
6530 test_MFCreateMediaEvent();
6531 test_attributes();
6532 test_sample();
6533 test_file_stream();
6534 test_MFCreateMFByteStreamOnStream();
6535 test_system_memory_buffer();
6536 test_source_resolver();
6537 test_MFCreateAsyncResult();
6538 test_allocate_queue();
6539 test_MFCopyImage();
6540 test_MFCreateCollection();
6541 test_MFHeapAlloc();
6542 test_scheduled_items();
6543 test_serial_queue();
6544 test_periodic_callback();
6545 test_event_queue();
6546 test_presentation_descriptor();
6547 test_system_time_source();
6548 test_MFInvokeCallback();
6549 test_stream_descriptor();
6550 test_MFCalculateImageSize();
6551 test_MFCompareFullToPartialMediaType();
6552 test_attributes_serialization();
6553 test_wrapped_media_type();
6554 test_MFCreateWaveFormatExFromMFMediaType();
6555 test_async_create_file();
6556 test_local_handlers();
6557 test_create_property_store();
6558 test_dxgi_device_manager();
6559 test_MFCreateTransformActivate();
6560 test_MFTRegisterLocal();
6561 test_queue_com();
6562 test_MFGetStrideForBitmapInfoHeader();
6563 test_MFCreate2DMediaBuffer();
6564 test_MFCreateMediaBufferFromMediaType();
6565 test_MFInitMediaTypeFromWaveFormatEx();
6566 test_MFCreateMFVideoFormatFromMFMediaType();
6567 test_MFCreateDXSurfaceBuffer();
6568 test_MFCreateTrackedSample();
6569 test_MFFrameRateToAverageTimePerFrame();
6570 test_MFMapDXGIFormatToDX9Format();
6571 test_dxgi_surface_buffer();
6572 test_sample_allocator();
6573 test_MFMapDX9FormatToDXGIFormat();
6575 CoUninitialize();