mfplat/tests: Mark some tests as broken on Win 8 and 10 v1507.
[wine.git] / dlls / mfplat / tests / mfplat.c
blob375947da02858ab9809ececaaf74bd8f16eee430
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>
23 #include <limits.h>
25 #define COBJMACROS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "ole2.h"
32 #include "mfapi.h"
33 #include "mfidl.h"
34 #include "mferror.h"
35 #include "mfreadwrite.h"
36 #include "propvarutil.h"
37 #include "strsafe.h"
38 #include "evr.h"
40 #include "wine/test.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"
49 #include "dxva2api.h"
50 #include "d3d12.h"
51 #undef EXTERN_GUID
52 #define EXTERN_GUID DEFINE_GUID
53 #include "mfd3d12.h"
55 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
56 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
57 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
58 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
60 extern const CLSID CLSID_FileSchemePlugin;
62 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
63 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
64 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
65 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
67 static BOOL is_win8_plus;
69 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
70 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
72 ULONG rc;
73 IUnknown_AddRef(obj);
74 rc = IUnknown_Release(obj);
75 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %ld, expected %ld.\n", rc, ref);
78 static ULONG get_refcount(void *iface)
80 IUnknown *unknown = iface;
81 IUnknown_AddRef(unknown);
82 return IUnknown_Release(unknown);
85 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
86 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
88 IUnknown *iface = iface_ptr;
89 HRESULT hr, expected_hr;
90 IUnknown *unk;
92 expected_hr = supported ? S_OK : E_NOINTERFACE;
94 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
95 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
96 if (SUCCEEDED(hr))
97 IUnknown_Release(unk);
100 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
101 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
103 IUnknown *iface = iface_ptr;
104 HRESULT hr, expected_hr;
105 IMFGetService *gs;
106 IUnknown *unk;
108 expected_hr = supported ? S_OK : E_NOINTERFACE;
110 if (SUCCEEDED(hr = IUnknown_QueryInterface(iface, &IID_IMFGetService, (void **)&gs)))
112 hr = IMFGetService_GetService(gs, service, iid, (void **)&unk);
113 IMFGetService_Release(gs);
115 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr);
116 if (SUCCEEDED(hr))
117 IUnknown_Release(unk);
120 struct d3d11_resource_readback
122 ID3D11Resource *resource;
123 D3D11_MAPPED_SUBRESOURCE map_desc;
124 ID3D11DeviceContext *immediate_context;
125 unsigned int width, height, depth, sub_resource_idx;
128 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
129 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
130 ID3D11Device *device, struct d3d11_resource_readback *rb)
132 HRESULT hr;
134 rb->resource = readback_resource;
135 rb->width = width;
136 rb->height = height;
137 rb->depth = depth;
138 rb->sub_resource_idx = sub_resource_idx;
140 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
142 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
143 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
144 rb->resource, sub_resource_idx, D3D11_MAP_READ, 0, &rb->map_desc)))
146 trace("Failed to map resource, hr %#lx.\n", hr);
147 ID3D11Resource_Release(rb->resource);
148 rb->resource = NULL;
149 ID3D11DeviceContext_Release(rb->immediate_context);
150 rb->immediate_context = NULL;
154 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
155 struct d3d11_resource_readback *rb)
157 D3D11_TEXTURE2D_DESC texture_desc;
158 ID3D11Resource *rb_texture;
159 unsigned int miplevel;
160 ID3D11Device *device;
161 HRESULT hr;
163 memset(rb, 0, sizeof(*rb));
165 ID3D11Texture2D_GetDevice(texture, &device);
167 ID3D11Texture2D_GetDesc(texture, &texture_desc);
168 texture_desc.Usage = D3D11_USAGE_STAGING;
169 texture_desc.BindFlags = 0;
170 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
171 texture_desc.MiscFlags = 0;
172 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
174 trace("Failed to create texture, hr %#lx.\n", hr);
175 ID3D11Device_Release(device);
176 return;
179 miplevel = sub_resource_idx % texture_desc.MipLevels;
180 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
181 max(1, texture_desc.Width >> miplevel),
182 max(1, texture_desc.Height >> miplevel),
183 1, sub_resource_idx, device, rb);
185 ID3D11Device_Release(device);
188 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb)
190 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
191 ID3D11Resource_Release(rb->resource);
192 ID3D11DeviceContext_Release(rb->immediate_context);
195 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
196 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
198 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
201 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
203 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
206 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
208 return get_d3d11_readback_u32(rb, x, y, z);
211 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
213 struct d3d11_resource_readback rb;
214 DWORD color;
216 get_d3d11_texture2d_readback(texture, 0, &rb);
217 color = get_d3d11_readback_color(&rb, x, y, 0);
218 release_d3d11_resource_readback(&rb);
220 return color;
223 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
224 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
225 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
226 static HRESULT (WINAPI *pD3D12CreateDevice)(IUnknown *adapter, D3D_FEATURE_LEVEL minimum_feature_level,
227 REFIID iid, void **device);
229 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
231 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
232 DWORD width, DWORD lines);
233 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
234 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
235 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
236 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
237 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
238 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
239 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
240 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
241 IMFActivate *activate);
242 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
243 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
244 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
245 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
246 const MFT_REGISTER_TYPE_INFO* output_types);
247 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
248 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
249 const MFT_REGISTER_TYPE_INFO *output_types);
250 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
251 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
252 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
253 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
254 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
255 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
256 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
257 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
258 IMFMediaBuffer **buffer);
259 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
260 DWORD min_alignment, IMFMediaBuffer **buffer);
261 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
262 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
263 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
264 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
265 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
266 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
267 IMFMediaBuffer **buffer);
268 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
269 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
270 static HRESULT (WINAPI *pMFLockDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
271 static HRESULT (WINAPI *pMFUnlockDXGIDeviceManager)(void);
272 static HRESULT (WINAPI *pMFInitVideoFormat_RGB)(MFVIDEOFORMAT *format, DWORD width, DWORD height, DWORD d3dformat);
274 static HWND create_window(void)
276 RECT r = {0, 0, 640, 480};
278 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
280 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
281 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
284 static IDirect3DDevice9 *create_d3d9_device(IDirect3D9 *d3d9, HWND focus_window)
286 D3DPRESENT_PARAMETERS present_parameters = {0};
287 IDirect3DDevice9 *device = NULL;
289 present_parameters.BackBufferWidth = 640;
290 present_parameters.BackBufferHeight = 480;
291 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
292 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
293 present_parameters.hDeviceWindow = focus_window;
294 present_parameters.Windowed = TRUE;
295 present_parameters.EnableAutoDepthStencil = TRUE;
296 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
297 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
299 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
300 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
302 return device;
305 static const WCHAR fileschemeW[] = L"file://";
307 static WCHAR *load_resource(const WCHAR *name)
309 static WCHAR pathW[MAX_PATH];
310 DWORD written;
311 HANDLE file;
312 HRSRC res;
313 void *ptr;
315 GetTempPathW(ARRAY_SIZE(pathW), pathW);
316 lstrcatW(pathW, name);
318 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
319 NULL, CREATE_ALWAYS, 0, 0);
320 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld\n",
321 wine_dbgstr_w(pathW), GetLastError());
323 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
324 ok(res != 0, "couldn't find resource\n");
325 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
326 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
327 &written, NULL);
328 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
329 "couldn't write resource\n" );
330 CloseHandle(file);
332 return pathW;
335 struct test_callback
337 IMFAsyncCallback IMFAsyncCallback_iface;
338 LONG refcount;
339 HANDLE event;
340 DWORD param;
341 IMFMediaEvent *media_event;
344 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
346 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
349 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
351 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
352 IsEqualIID(riid, &IID_IUnknown))
354 *obj = iface;
355 IMFAsyncCallback_AddRef(iface);
356 return S_OK;
359 *obj = NULL;
360 return E_NOINTERFACE;
363 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
365 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
366 return InterlockedIncrement(&callback->refcount);
369 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
371 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
372 ULONG refcount = InterlockedDecrement(&callback->refcount);
374 if (!refcount)
375 free(callback);
377 return refcount;
380 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
382 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
383 return E_NOTIMPL;
386 static BOOL check_clsid(CLSID *clsids, UINT32 count)
388 int i;
389 for (i = 0; i < count; i++)
391 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
392 return TRUE;
394 return FALSE;
397 static void test_register(void)
399 MFT_REGISTER_TYPE_INFO *in_types, *out_types;
400 WCHAR name[] = L"Wine test";
401 MFT_REGISTER_TYPE_INFO input[] =
403 { DUMMY_CLSID, DUMMY_GUID1 }
405 MFT_REGISTER_TYPE_INFO output[] =
407 { DUMMY_CLSID, DUMMY_GUID2 }
409 UINT32 count, in_count, out_count;
410 IMFAttributes *attributes;
411 WCHAR *mft_name;
412 CLSID *clsids;
413 HRESULT hr, ret;
415 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
416 if (ret == E_ACCESSDENIED)
418 win_skip("Not enough permissions to register a transform.\n");
419 return;
421 ok(ret == S_OK, "Failed to register dummy transform, hr %#lx.\n", ret);
423 if(0)
425 /* NULL name crashes on windows */
426 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
427 ok(ret == E_INVALIDARG, "Unexpected hr %#lx.\n", ret);
430 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
431 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
433 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
434 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
436 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
437 ok(ret == S_OK, "Failed to register dummy filter: %lx\n", ret);
439 if(0)
441 /* NULL clsids/count crashes on windows (vista) */
442 count = 0;
443 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
444 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
445 ok(count == 0, "Expected count == 0\n");
447 clsids = NULL;
448 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
449 ok(ret == E_POINTER, "Failed to enumerate filters: %lx\n", ret);
451 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, NULL, NULL, NULL, NULL, NULL);
452 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
453 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
454 CoTaskMemFree(mft_name);
456 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, NULL);
457 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
459 in_count = out_count = 1;
460 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, &in_count, NULL, &out_count, NULL);
461 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
462 ok(!in_count, "Unexpected count %u.\n", in_count);
463 ok(!out_count, "Unexpected count %u.\n", out_count);
465 hr = MFTGetInfo(DUMMY_CLSID, NULL, NULL, NULL, NULL, NULL, &attributes);
466 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
467 ok(!!attributes, "Unexpected attributes.\n");
468 IMFAttributes_Release(attributes);
470 hr = MFTGetInfo(DUMMY_CLSID, &mft_name, &in_types, &in_count, &out_types, &out_count, &attributes);
471 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
472 ok(!lstrcmpW(mft_name, L"Wine test"), "Unexpected name %s.\n", wine_dbgstr_w(mft_name));
473 ok(!!in_types, "Unexpected pointer.\n");
474 ok(!!out_types, "Unexpected pointer.\n");
475 ok(in_count == 1, "Unexpected count %u.\n", in_count);
476 ok(out_count == 1, "Unexpected count %u.\n", out_count);
477 ok(IsEqualGUID(&in_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
478 wine_dbgstr_guid(&in_types->guidMajorType));
479 ok(IsEqualGUID(&in_types->guidSubtype, &DUMMY_GUID1), "Unexpected type guid %s.\n",
480 wine_dbgstr_guid(&in_types->guidSubtype));
481 ok(IsEqualGUID(&out_types->guidMajorType, &DUMMY_CLSID), "Unexpected type guid %s.\n",
482 wine_dbgstr_guid(&out_types->guidMajorType));
483 ok(IsEqualGUID(&out_types->guidSubtype, &DUMMY_GUID2), "Unexpected type guid %s.\n",
484 wine_dbgstr_guid(&out_types->guidSubtype));
485 ok(!!attributes, "Unexpected attributes.\n");
486 count = 1;
487 hr = IMFAttributes_GetCount(attributes, &count);
488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
489 ok(!count, "Unexpected count %u.\n", count);
490 CoTaskMemFree(mft_name);
491 CoTaskMemFree(in_types);
492 CoTaskMemFree(out_types);
493 IMFAttributes_Release(attributes);
495 count = 0;
496 clsids = NULL;
497 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
498 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
499 ok(count > 0, "Expected count > 0\n");
500 ok(clsids != NULL, "Expected clsids != NULL\n");
501 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
502 CoTaskMemFree(clsids);
504 count = 0;
505 clsids = NULL;
506 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
507 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
508 ok(count > 0, "Expected count > 0\n");
509 ok(clsids != NULL, "Expected clsids != NULL\n");
510 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
511 CoTaskMemFree(clsids);
513 count = 0;
514 clsids = NULL;
515 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
516 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
517 ok(count > 0, "Expected count > 0\n");
518 ok(clsids != NULL, "Expected clsids != NULL\n");
519 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
520 CoTaskMemFree(clsids);
522 count = 0;
523 clsids = NULL;
524 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
525 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
526 ok(count > 0, "Expected count > 0\n");
527 ok(clsids != NULL, "Expected clsids != NULL\n");
528 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
529 CoTaskMemFree(clsids);
531 /* exchange input and output */
532 count = 0;
533 clsids = NULL;
534 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
535 ok(ret == S_OK, "Failed to enumerate filters: %lx\n", ret);
536 ok(!count, "got %d\n", count);
537 ok(clsids == NULL, "Expected clsids == NULL\n");
539 ret = MFTUnregister(DUMMY_CLSID);
540 ok(ret == S_OK ||
541 /* w7pro64 */
542 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
544 ret = MFTUnregister(DUMMY_CLSID);
545 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "Unexpected hr %#lx.\n", ret);
548 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
550 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
551 IMFSourceResolver *resolver;
552 IUnknown *object, *object2;
553 MF_OBJECT_TYPE obj_type;
554 HRESULT hr;
556 ok(!!result, "Unexpected result object.\n");
558 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
560 object = NULL;
561 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
562 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
564 hr = IMFAsyncResult_GetObject(result, &object2);
565 ok(hr == S_OK, "Failed to get result object, hr %#lx.\n", hr);
566 ok(object2 == object, "Unexpected object.\n");
568 if (object)
569 IUnknown_Release(object);
570 IUnknown_Release(object2);
572 SetEvent(callback->event);
574 return S_OK;
577 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
579 testcallback_QueryInterface,
580 testcallback_AddRef,
581 testcallback_Release,
582 testcallback_GetParameters,
583 test_create_from_url_callback_Invoke,
586 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
588 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
589 IMFSchemeHandler *handler;
590 IUnknown *object, *object2;
591 MF_OBJECT_TYPE obj_type;
592 HRESULT hr;
594 ok(!!result, "Unexpected result object.\n");
596 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
598 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
599 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
601 if (SUCCEEDED(hr))
603 hr = IMFAsyncResult_GetObject(result, &object2);
604 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
606 IUnknown_Release(object);
609 SetEvent(callback->event);
611 return S_OK;
614 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
616 testcallback_QueryInterface,
617 testcallback_AddRef,
618 testcallback_Release,
619 testcallback_GetParameters,
620 test_create_from_file_handler_callback_Invoke,
623 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
625 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
626 IMFMediaEventGenerator *generator;
627 HRESULT hr;
629 ok(!!result, "Unexpected result object.\n");
631 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
633 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
634 ok(hr == S_OK, "Failed to create an object, hr %#lx.\n", hr);
636 SetEvent(callback->event);
638 return S_OK;
641 static const IMFAsyncCallbackVtbl events_callback_vtbl =
643 testcallback_QueryInterface,
644 testcallback_AddRef,
645 testcallback_Release,
646 testcallback_GetParameters,
647 source_events_callback_Invoke,
650 static const IMFAsyncCallbackVtbl testcallbackvtbl;
652 static struct test_callback * create_test_callback(const IMFAsyncCallbackVtbl *vtbl)
654 struct test_callback *callback = calloc(1, sizeof(*callback));
656 callback->IMFAsyncCallback_iface.lpVtbl = vtbl ? vtbl : &testcallbackvtbl;
657 callback->refcount = 1;
659 return callback;
662 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
664 struct test_callback *callback;
665 MediaEventType event_type;
666 BOOL ret = FALSE;
667 HRESULT hr;
669 callback = create_test_callback(&events_callback_vtbl);
670 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
672 for (;;)
674 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback->IMFAsyncCallback_iface,
675 (IUnknown *)generator);
676 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
678 if (WaitForSingleObject(callback->event, 1000) == WAIT_TIMEOUT)
680 ok(0, "timeout\n");
681 break;
684 Sleep(10);
686 hr = IMFMediaEvent_GetType(callback->media_event, &event_type);
687 ok(hr == S_OK, "Failed to event type, hr %#lx.\n", hr);
689 if ((ret = (event_type == expected_event_type)))
691 if (value)
693 hr = IMFMediaEvent_GetValue(callback->media_event, value);
694 ok(hr == S_OK, "Failed to get value of event, hr %#lx.\n", hr);
697 break;
701 CloseHandle(callback->event);
702 if (callback->media_event)
703 IMFMediaEvent_Release(callback->media_event);
704 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
706 return ret;
709 static void test_source_resolver(void)
711 struct test_callback *callback, *callback2;
712 IMFSourceResolver *resolver, *resolver2;
713 IMFPresentationDescriptor *descriptor;
714 IMFSchemeHandler *scheme_handler;
715 IMFMediaStream *video_stream;
716 IMFAttributes *attributes;
717 IMFMediaSource *mediasource;
718 IMFMediaTypeHandler *handler;
719 IMFMediaType *media_type;
720 BOOL selected, do_uninit;
721 MF_OBJECT_TYPE obj_type;
722 IMFStreamDescriptor *sd;
723 IUnknown *cancel_cookie;
724 IMFByteStream *stream;
725 IMFGetService *get_service;
726 IMFRateSupport *rate_support;
727 WCHAR pathW[MAX_PATH];
728 int i, sample_count;
729 WCHAR *filename;
730 PROPVARIANT var;
731 HRESULT hr;
732 GUID guid;
733 float rate;
734 UINT32 rotation;
736 if (!pMFCreateSourceResolver)
738 win_skip("MFCreateSourceResolver() not found\n");
739 return;
742 callback = create_test_callback(&test_create_from_url_callback_vtbl);
743 callback2 = create_test_callback(&test_create_from_file_handler_callback_vtbl);
745 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
746 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
748 hr = pMFCreateSourceResolver(NULL);
749 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
751 hr = pMFCreateSourceResolver(&resolver);
752 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
754 hr = pMFCreateSourceResolver(&resolver2);
755 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
756 ok(resolver != resolver2, "Expected new instance\n");
758 IMFSourceResolver_Release(resolver2);
760 filename = load_resource(L"test.mp4");
762 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
763 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
765 hr = IMFSourceResolver_CreateObjectFromByteStream(
766 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
767 &obj_type, (IUnknown **)&mediasource);
768 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
770 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
771 NULL, (IUnknown **)&mediasource);
772 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
774 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
775 &obj_type, NULL);
776 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
778 IMFByteStream_Release(stream);
780 /* Create from URL. */
781 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
783 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
784 (IUnknown **)&stream);
785 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
787 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
788 (IUnknown **)&stream);
789 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
790 IMFByteStream_Release(stream);
792 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
793 &cancel_cookie, &callback->IMFAsyncCallback_iface, (IUnknown *)resolver);
794 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
795 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
796 IUnknown_Release(cancel_cookie);
798 if (SUCCEEDED(hr))
799 WaitForSingleObject(callback->event, INFINITE);
801 /* With explicit scheme. */
802 lstrcpyW(pathW, fileschemeW);
803 lstrcatW(pathW, filename);
805 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
806 (IUnknown **)&stream);
807 ok(hr == S_OK, "Failed to resolve url, hr %#lx.\n", hr);
808 IMFByteStream_Release(stream);
810 /* We have to create a new bytestream here, because all following
811 * calls to CreateObjectFromByteStream will fail. */
812 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
813 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
815 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
816 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
817 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
818 ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr);
819 IMFAttributes_Release(attributes);
821 /* Start of gstreamer dependent tests */
823 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
824 &obj_type, (IUnknown **)&mediasource);
825 if (strcmp(winetest_platform, "wine"))
826 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
827 if (FAILED(hr))
829 IMFByteStream_Release(stream);
830 IMFSourceResolver_Release(resolver);
832 hr = MFShutdown();
833 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
835 DeleteFileW(filename);
836 return;
838 ok(mediasource != NULL, "got %p\n", mediasource);
839 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
841 check_interface(mediasource, &IID_IMFGetService, TRUE);
842 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
844 hr = IMFMediaSource_QueryInterface(mediasource, &IID_IMFGetService, (void**)&get_service);
845 ok(hr == S_OK, "Failed to get service interface, hr %#lx.\n", hr);
847 hr = IMFGetService_GetService(get_service, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void**)&rate_support);
848 ok(hr == S_OK, "Failed to get rate support interface, hr %#lx.\n", hr);
850 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
851 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
852 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
853 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
854 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
855 ok(rate == 1e6f, "Unexpected fastest rate %f.\n", rate);
856 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
857 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
858 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
859 hr = IMFRateSupport_GetFastestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
860 ok(hr == S_OK, "Failed to query fastest rate, hr %#lx.\n", hr);
861 ok(rate == -1e6f, "Unexpected fastest rate %f.\n", rate);
863 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, FALSE, &rate);
864 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
865 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
866 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_FORWARD, TRUE, &rate);
867 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
868 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
869 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, FALSE, &rate);
870 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
871 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
872 hr = IMFRateSupport_GetSlowestRate(rate_support, MFRATE_REVERSE, TRUE, &rate);
873 ok(hr == S_OK, "Failed to query slowest rate, hr %#lx.\n", hr);
874 ok(rate == 0.0f, "Unexpected slowest rate %f.\n", rate);
876 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, NULL);
877 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
878 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 0.0f, &rate);
879 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
880 ok(rate == 0.0f, "Unexpected rate %f.\n", rate);
882 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1.0f, &rate);
883 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
884 ok(rate == 1.0f, "Unexpected rate %f.\n", rate);
885 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1.0f, &rate);
886 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
887 ok(rate == -1.0f, "Unexpected rate %f.\n", rate);
888 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, 1e6f + 1.0f, &rate);
889 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
890 ok(rate == 1e6f + 1.0f || broken(rate == 1e6f) /* Win7 */, "Unexpected %f.\n", rate);
891 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f, &rate);
892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
893 ok(rate == -1e6f, "Unexpected rate %f.\n", rate);
895 hr = IMFRateSupport_IsRateSupported(rate_support, FALSE, -1e6f - 1.0f, &rate);
896 ok(hr == MF_E_UNSUPPORTED_RATE, "Unexpected hr %#lx.\n", hr);
897 ok(rate == -1e6f - 1.0f || broken(rate == -1e6f) /* Win7 */, "Unexpected rate %f.\n", rate);
899 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
900 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
901 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#lx.\n", hr);
902 ok(descriptor != NULL, "got %p\n", descriptor);
904 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
905 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
907 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
908 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
909 IMFStreamDescriptor_Release(sd);
911 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
912 ok(hr == S_OK, "Failed to get stream major type, hr %#lx.\n", hr);
914 /* Check major/minor type for the test media. */
915 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
917 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
918 ok(hr == S_OK, "Failed to get current media type, hr %#lx.\n", hr);
919 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
920 ok(hr == S_OK, "Failed to get media sub type, hr %#lx.\n", hr);
921 todo_wine
922 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
924 hr = IMFMediaType_GetUINT32(media_type, &MF_MT_VIDEO_ROTATION, &rotation);
925 ok(hr == S_OK || broken(hr == MF_E_ATTRIBUTENOTFOUND) /* Win7 */, "Failed to get rotation, hr %#lx.\n", hr);
926 if (hr == S_OK)
927 ok(rotation == MFVideoRotationFormat_0, "Got wrong rotation %u.\n", rotation);
929 IMFMediaType_Release(media_type);
931 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
932 ok(hr == S_OK, "Failed to select video stream, hr %#lx.\n", hr);
934 var.vt = VT_EMPTY;
935 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
936 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
938 video_stream = NULL;
939 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
941 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
942 video_stream = (IMFMediaStream *)var.punkVal;
945 hr = IMFMediaSource_Pause(mediasource);
946 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
947 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
948 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
950 var.vt = VT_EMPTY;
951 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
952 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
954 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
955 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
957 hr = IMFMediaSource_Pause(mediasource);
958 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
959 if (get_event((IMFMediaEventGenerator *)mediasource, MESourcePaused, &var))
960 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
962 var.vt = VT_I8;
963 var.uhVal.QuadPart = 0;
964 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
965 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
967 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceSeeked, &var))
968 ok(var.vt == VT_I8, "Unexpected value type.\n");
970 hr = IMFMediaSource_Stop(mediasource);
971 ok(hr == S_OK, "Failed to pause media source, hr %#lx.\n", hr);
972 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStopped, &var))
973 ok(var.vt == VT_EMPTY, "Unexpected value type.\n");
975 var.vt = VT_I8;
976 var.uhVal.QuadPart = 0;
977 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
978 ok(hr == S_OK, "Failed to start media source, hr %#lx.\n", hr);
980 if (get_event((IMFMediaEventGenerator *)mediasource, MESourceStarted, &var))
981 ok(var.vt == VT_I8, "Unexpected value type.\n");
983 sample_count = 10;
985 for (i = 0; i < sample_count; ++i)
987 hr = IMFMediaStream_RequestSample(video_stream, NULL);
988 ok(hr == S_OK, "Failed to request sample %u, hr %#lx.\n", i + 1, hr);
989 if (hr != S_OK)
990 break;
993 for (i = 0; i < sample_count; ++i)
995 static const LONGLONG MILLI_TO_100_NANO = 10000;
996 LONGLONG duration, time;
997 DWORD buffer_count;
998 IMFSample *sample;
999 BOOL ret;
1001 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
1002 ok(ret, "Sample %u not received.\n", i + 1);
1003 if (!ret)
1004 break;
1006 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
1007 sample = (IMFSample *)var.punkVal;
1009 hr = IMFSample_GetBufferCount(sample, &buffer_count);
1010 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
1011 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
1013 hr = IMFSample_GetSampleDuration(sample, &duration);
1014 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
1015 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
1017 hr = IMFSample_GetSampleTime(sample, &time);
1018 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
1019 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
1021 IMFSample_Release(sample);
1024 if (i == sample_count)
1026 IMFMediaEvent *event;
1028 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
1029 Sleep(100);
1030 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
1031 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
1033 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1034 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1035 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
1039 hr = IMFMediaStream_RequestSample(video_stream, NULL);
1040 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#lx.\n", hr);
1042 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
1044 IMFMediaStream_Release(video_stream);
1045 IMFMediaTypeHandler_Release(handler);
1046 IMFPresentationDescriptor_Release(descriptor);
1048 hr = IMFMediaSource_Shutdown(mediasource);
1049 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1051 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
1052 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
1054 IMFRateSupport_Release(rate_support);
1055 IMFGetService_Release(get_service);
1056 IMFMediaSource_Release(mediasource);
1057 IMFByteStream_Release(stream);
1059 /* Create directly through scheme handler. */
1060 hr = CoInitialize(NULL);
1061 ok(SUCCEEDED(hr), "Failed to initialize, hr %#lx.\n", hr);
1062 do_uninit = hr == S_OK;
1064 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
1065 (void **)&scheme_handler);
1066 ok(hr == S_OK, "Failed to create handler object, hr %#lx.\n", hr);
1068 callback2->event = callback->event;
1069 cancel_cookie = NULL;
1070 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
1071 &callback2->IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
1072 ok(hr == S_OK, "Create request failed, hr %#lx.\n", hr);
1073 ok(!!cancel_cookie, "Unexpected cancel object.\n");
1074 IUnknown_Release(cancel_cookie);
1076 WaitForSingleObject(callback2->event, INFINITE);
1078 IMFSchemeHandler_Release(scheme_handler);
1080 if (do_uninit)
1081 CoUninitialize();
1083 CloseHandle(callback->event);
1085 IMFSourceResolver_Release(resolver);
1087 hr = MFShutdown();
1088 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
1090 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
1091 IMFAsyncCallback_Release(&callback2->IMFAsyncCallback_iface);
1093 DeleteFileW(filename);
1096 static void init_functions(void)
1098 HMODULE mod = GetModuleHandleA("mfplat.dll");
1100 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
1101 X(MFAddPeriodicCallback);
1102 X(MFAllocateSerialWorkQueue);
1103 X(MFAllocateWorkQueueEx);
1104 X(MFCopyImage);
1105 X(MFCreate2DMediaBuffer);
1106 X(MFCreateDXGIDeviceManager);
1107 X(MFCreateDXGISurfaceBuffer);
1108 X(MFCreateDXSurfaceBuffer);
1109 X(MFCreateSourceResolver);
1110 X(MFCreateMediaBufferFromMediaType);
1111 X(MFCreateMFByteStreamOnStream);
1112 X(MFCreateTrackedSample);
1113 X(MFCreateTransformActivate);
1114 X(MFCreateVideoMediaTypeFromSubtype);
1115 X(MFCreateVideoSampleAllocatorEx);
1116 X(MFGetPlaneSize);
1117 X(MFGetStrideForBitmapInfoHeader);
1118 X(MFInitVideoFormat_RGB);
1119 X(MFLockDXGIDeviceManager);
1120 X(MFLockSharedWorkQueue);
1121 X(MFMapDX9FormatToDXGIFormat);
1122 X(MFMapDXGIFormatToDX9Format);
1123 X(MFPutWaitingWorkItem);
1124 X(MFRegisterLocalByteStreamHandler);
1125 X(MFRegisterLocalSchemeHandler);
1126 X(MFRemovePeriodicCallback);
1127 X(MFTEnumEx);
1128 X(MFTRegisterLocal);
1129 X(MFTRegisterLocalByCLSID);
1130 X(MFTUnregisterLocal);
1131 X(MFTUnregisterLocalByCLSID);
1132 X(MFUnlockDXGIDeviceManager);
1134 if ((mod = LoadLibraryA("d3d11.dll")))
1136 X(D3D11CreateDevice);
1139 if ((mod = LoadLibraryA("d3d12.dll")))
1141 X(D3D12CreateDevice);
1144 mod = GetModuleHandleA("ole32.dll");
1146 X(CoGetApartmentType);
1147 #undef X
1149 is_win8_plus = pMFPutWaitingWorkItem != NULL;
1152 static void test_media_type(void)
1154 IMFMediaType *mediatype, *mediatype2;
1155 IMFVideoMediaType *video_type;
1156 IUnknown *unk, *unk2;
1157 BOOL compressed;
1158 DWORD flags;
1159 UINT count;
1160 HRESULT hr;
1161 GUID guid;
1163 if(0)
1165 /* Crash on Windows Vista/7 */
1166 hr = MFCreateMediaType(NULL);
1167 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1170 hr = MFCreateMediaType(&mediatype);
1171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1173 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1174 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1176 compressed = FALSE;
1177 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1178 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1179 ok(compressed, "Unexpected value %d.\n", compressed);
1181 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
1182 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1184 compressed = FALSE;
1185 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1186 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1187 ok(compressed, "Unexpected value %d.\n", compressed);
1189 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 0);
1190 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1192 compressed = FALSE;
1193 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1194 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1195 ok(compressed, "Unexpected value %d.\n", compressed);
1197 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
1198 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1200 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 1);
1201 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1203 compressed = TRUE;
1204 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1205 ok(hr == S_OK, "Failed to get media type property, hr %#lx.\n", hr);
1206 ok(!compressed, "Unexpected value %d.\n", compressed);
1208 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_COMPRESSED);
1209 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1211 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1212 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1214 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1215 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
1216 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1218 /* IsEqual() */
1219 hr = MFCreateMediaType(&mediatype2);
1220 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
1222 flags = 0xdeadbeef;
1223 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1224 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1225 ok(flags == 0, "Unexpected flags %#lx.\n", flags);
1227 /* Different major types. */
1228 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1229 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1231 flags = 0;
1232 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1233 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1234 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1235 "Unexpected flags %#lx.\n", flags);
1237 /* Same major types, different subtypes. */
1238 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1239 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
1241 flags = 0;
1242 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1244 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1245 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#lx.\n", flags);
1247 /* Different user data. */
1248 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1249 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
1251 flags = 0;
1252 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1253 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1254 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1255 "Unexpected flags %#lx.\n", flags);
1257 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1258 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1260 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1261 ok(hr == S_OK, "Failed to set subtype, hr %#lx.\n", hr);
1263 flags = 0;
1264 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1265 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
1266 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1267 "Unexpected flags %#lx.\n", flags);
1269 IMFMediaType_Release(mediatype2);
1270 IMFMediaType_Release(mediatype);
1272 /* IMFVideoMediaType */
1273 hr = MFCreateMediaType(&mediatype);
1274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1276 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1278 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1279 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1280 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1281 IUnknown_Release(unk);
1283 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1284 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1286 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1289 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1291 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1292 IUnknown_Release(unk2);
1294 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1295 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1296 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1297 IUnknown_Release(unk2);
1299 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1301 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1302 IUnknown_Release(unk2);
1304 IUnknown_Release(unk);
1305 IMFMediaType_Release(mediatype);
1307 if (pMFCreateVideoMediaTypeFromSubtype)
1309 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1312 check_interface(video_type, &IID_IMFMediaType, TRUE);
1313 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1315 /* Major and subtype are set on creation. */
1316 hr = IMFVideoMediaType_GetCount(video_type, &count);
1317 ok(count == 2, "Unexpected attribute count %#lx.\n", hr);
1319 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1322 hr = IMFVideoMediaType_GetCount(video_type, &count);
1323 ok(!count, "Unexpected attribute count %#lx.\n", hr);
1325 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1327 IMFVideoMediaType_Release(video_type);
1329 else
1330 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1332 /* IMFAudioMediaType */
1333 hr = MFCreateMediaType(&mediatype);
1334 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1336 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1338 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1340 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1341 IUnknown_Release(unk);
1343 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1344 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
1346 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1347 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1349 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1350 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1351 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1352 IUnknown_Release(unk2);
1354 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1355 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1356 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1357 IUnknown_Release(unk2);
1359 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1361 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1362 IUnknown_Release(unk2);
1364 IUnknown_Release(unk);
1366 IMFMediaType_Release(mediatype);
1369 static void test_MFCreateMediaEvent(void)
1371 HRESULT hr;
1372 IMFMediaEvent *mediaevent;
1374 MediaEventType type;
1375 GUID extended_type;
1376 HRESULT status;
1377 PROPVARIANT value;
1379 PropVariantInit(&value);
1380 value.vt = VT_UNKNOWN;
1382 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1383 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1385 PropVariantClear(&value);
1387 hr = IMFMediaEvent_GetType(mediaevent, &type);
1388 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1389 ok(type == MEError, "got %#lx\n", type);
1391 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1392 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1393 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1394 wine_dbgstr_guid(&extended_type));
1396 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1398 ok(status == E_FAIL, "Unexpected hr %#lx.\n", status);
1400 PropVariantInit(&value);
1401 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1402 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1403 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1404 PropVariantClear(&value);
1406 IMFMediaEvent_Release(mediaevent);
1408 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1409 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1411 hr = IMFMediaEvent_GetType(mediaevent, &type);
1412 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1413 ok(type == MEUnknown, "got %#lx\n", type);
1415 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1416 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1417 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1418 wine_dbgstr_guid(&extended_type));
1420 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1421 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1422 ok(status == S_OK, "Unexpected hr %#lx.\n", status);
1424 PropVariantInit(&value);
1425 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1426 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1427 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1428 PropVariantClear(&value);
1430 IMFMediaEvent_Release(mediaevent);
1433 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1434 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1436 UINT32 count = expected + 1;
1437 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1438 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
1439 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1442 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1443 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1445 MF_ATTRIBUTE_TYPE type;
1446 HRESULT hr;
1448 hr = IMFAttributes_GetItemType(obj, key, &type);
1449 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
1450 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1453 static void test_attributes(void)
1455 static const WCHAR stringW[] = L"Wine";
1456 static const UINT8 blob[] = {0,1,2,3,4,5};
1457 IMFAttributes *attributes, *attributes1;
1458 UINT8 blob_value[256], *blob_buf = NULL;
1459 MF_ATTRIBUTES_MATCH_TYPE match_type;
1460 UINT32 value, string_length, size;
1461 PROPVARIANT propvar, ret_propvar;
1462 MF_ATTRIBUTE_TYPE type;
1463 double double_value;
1464 IUnknown *unk_value;
1465 WCHAR bufferW[256];
1466 UINT64 value64;
1467 WCHAR *string;
1468 BOOL result;
1469 HRESULT hr;
1470 GUID key;
1472 hr = MFCreateAttributes( &attributes, 3 );
1473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1475 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1476 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1478 CHECK_ATTR_COUNT(attributes, 0);
1479 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1480 ok(hr == S_OK, "Failed to set UINT32 value, hr %#lx.\n", hr);
1481 CHECK_ATTR_COUNT(attributes, 1);
1482 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1484 value = 0xdeadbeef;
1485 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1486 ok(hr == S_OK, "Failed to get UINT32 value, hr %#lx.\n", hr);
1487 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1489 value64 = 0xdeadbeef;
1490 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1491 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1492 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1494 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1495 ok(hr == S_OK, "Failed to set UINT64 value, hr %#lx.\n", hr);
1496 CHECK_ATTR_COUNT(attributes, 1);
1497 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1499 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1500 ok(hr == S_OK, "Failed to get UINT64 value, hr %#lx.\n", hr);
1501 ok(value64 == 65536, "Unexpected value.\n");
1503 value = 0xdeadbeef;
1504 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1505 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1506 ok(value == 0xdeadbeef, "Unexpected value.\n");
1508 IMFAttributes_Release(attributes);
1510 hr = MFCreateAttributes(&attributes, 0);
1511 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1513 PropVariantInit(&propvar);
1514 propvar.vt = MF_ATTRIBUTE_UINT32;
1515 U(propvar).ulVal = 123;
1516 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1517 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1518 PropVariantInit(&ret_propvar);
1519 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1520 U(ret_propvar).ulVal = 0xdeadbeef;
1521 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1522 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1523 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1524 PropVariantClear(&ret_propvar);
1525 CHECK_ATTR_COUNT(attributes, 1);
1527 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1528 ok(hr == S_OK, "Item check failed, hr %#lx.\n", hr);
1530 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1531 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1533 PropVariantInit(&ret_propvar);
1534 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1535 U(ret_propvar).pwszVal = NULL;
1536 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1537 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1538 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1539 PropVariantClear(&ret_propvar);
1541 PropVariantClear(&propvar);
1543 PropVariantInit(&propvar);
1544 propvar.vt = MF_ATTRIBUTE_UINT64;
1545 U(propvar).uhVal.QuadPart = 65536;
1546 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1547 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1548 PropVariantInit(&ret_propvar);
1549 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1550 U(ret_propvar).ulVal = 0xdeadbeef;
1551 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1552 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1553 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1554 PropVariantClear(&ret_propvar);
1555 PropVariantClear(&propvar);
1556 CHECK_ATTR_COUNT(attributes, 1);
1558 PropVariantInit(&propvar);
1559 propvar.vt = VT_I4;
1560 U(propvar).lVal = 123;
1561 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1562 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#lx.\n", hr);
1563 PropVariantInit(&ret_propvar);
1564 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1565 U(ret_propvar).lVal = 0xdeadbeef;
1566 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1567 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1568 PropVariantClear(&propvar);
1569 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1570 PropVariantClear(&ret_propvar);
1572 PropVariantInit(&propvar);
1573 propvar.vt = MF_ATTRIBUTE_UINT32;
1574 U(propvar).ulVal = 123;
1575 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1576 ok(hr == S_OK, "Failed to set item, hr %#lx.\n", hr);
1578 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1579 ok(hr == S_OK, "Failed to delete item, hr %#lx.\n", hr);
1580 CHECK_ATTR_COUNT(attributes, 2);
1582 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1583 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1584 CHECK_ATTR_COUNT(attributes, 2);
1586 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1587 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1588 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1589 PropVariantClear(&ret_propvar);
1590 PropVariantClear(&propvar);
1592 propvar.vt = MF_ATTRIBUTE_UINT64;
1593 U(propvar).uhVal.QuadPart = 65536;
1595 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1596 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1597 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1598 PropVariantClear(&ret_propvar);
1599 PropVariantClear(&propvar);
1601 /* Item ordering is not consistent across Windows version. */
1602 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1603 ok(hr == S_OK, "Failed to get item, hr %#lx.\n", hr);
1604 PropVariantClear(&ret_propvar);
1606 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1607 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1608 PropVariantClear(&ret_propvar);
1610 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1611 ok(hr == S_OK, "Failed to set double value, hr %#lx.\n", hr);
1612 CHECK_ATTR_COUNT(attributes, 3);
1613 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1615 double_value = 0xdeadbeef;
1616 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1617 ok(hr == S_OK, "Failed to get double value, hr %#lx.\n", hr);
1618 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1620 propvar.vt = MF_ATTRIBUTE_UINT64;
1621 U(propvar).uhVal.QuadPart = 22;
1622 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1623 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1624 ok(!result, "Unexpected result.\n");
1626 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1627 U(propvar).dblVal = 22.0;
1628 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1629 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1630 ok(result, "Unexpected result.\n");
1632 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1633 ok(hr == S_OK, "Failed to set string attribute, hr %#lx.\n", hr);
1634 CHECK_ATTR_COUNT(attributes, 3);
1635 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1637 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1638 ok(hr == S_OK, "Failed to get string length, hr %#lx.\n", hr);
1639 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1641 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, NULL);
1642 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1643 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1644 CoTaskMemFree(string);
1646 string_length = 0xdeadbeef;
1647 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1648 ok(hr == S_OK, "Failed to get allocated string, hr %#lx.\n", hr);
1649 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1650 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1651 CoTaskMemFree(string);
1653 string_length = 0xdeadbeef;
1654 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1655 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1656 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1657 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1658 memset(bufferW, 0, sizeof(bufferW));
1660 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1661 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
1662 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1663 memset(bufferW, 0, sizeof(bufferW));
1665 string_length = 0;
1666 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1667 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1668 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1669 ok(string_length, "Unexpected length.\n");
1671 string_length = 0xdeadbeef;
1672 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1673 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1674 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1676 /* VT_UNKNOWN */
1677 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1678 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1679 CHECK_ATTR_COUNT(attributes, 4);
1680 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1682 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1683 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1684 IUnknown_Release(unk_value);
1686 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1687 ok(hr == S_OK, "Failed to get value, hr %#lx.\n", hr);
1688 IUnknown_Release(unk_value);
1690 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1691 ok(hr == E_NOINTERFACE, "Unexpected hr %#lx.\n", hr);
1693 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1694 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1695 CHECK_ATTR_COUNT(attributes, 5);
1697 unk_value = NULL;
1698 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1699 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#lx.\n", hr);
1701 /* CopyAllItems() */
1702 hr = MFCreateAttributes(&attributes1, 0);
1703 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1704 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1705 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1706 CHECK_ATTR_COUNT(attributes, 5);
1707 CHECK_ATTR_COUNT(attributes1, 5);
1709 hr = IMFAttributes_DeleteAllItems(attributes1);
1710 ok(hr == S_OK, "Failed to delete items, hr %#lx.\n", hr);
1711 CHECK_ATTR_COUNT(attributes1, 0);
1713 propvar.vt = MF_ATTRIBUTE_UINT64;
1714 U(propvar).uhVal.QuadPart = 22;
1715 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1716 ok(hr == S_OK, "Failed to compare items, hr %#lx.\n", hr);
1717 ok(!result, "Unexpected result.\n");
1719 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1720 ok(hr == S_OK, "Failed to copy items, hr %#lx.\n", hr);
1721 CHECK_ATTR_COUNT(attributes, 0);
1723 /* Blob */
1724 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1725 ok(hr == S_OK, "Failed to set blob attribute, hr %#lx.\n", hr);
1726 CHECK_ATTR_COUNT(attributes, 1);
1727 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1728 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1729 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
1730 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1732 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1733 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1735 size = 0;
1736 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1737 ok(hr == S_OK, "Failed to get blob, hr %#lx.\n", hr);
1738 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1739 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1741 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1742 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1744 memset(blob_value, 0, sizeof(blob_value));
1745 size = 0;
1746 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1747 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1748 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1749 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1750 CoTaskMemFree(blob_buf);
1752 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, NULL);
1753 ok(hr == S_OK, "Failed to get allocated blob, hr %#lx.\n", hr);
1754 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1755 CoTaskMemFree(blob_buf);
1757 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1758 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
1760 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1761 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#lx.\n", hr);
1763 IMFAttributes_Release(attributes);
1764 IMFAttributes_Release(attributes1);
1766 /* Compare() */
1767 hr = MFCreateAttributes(&attributes, 0);
1768 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1769 hr = MFCreateAttributes(&attributes1, 0);
1770 ok(hr == S_OK, "Failed to create attributes object, hr %#lx.\n", hr);
1772 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1773 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
1775 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1777 result = FALSE;
1778 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1779 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1780 ok(result, "Unexpected result %d.\n", result);
1782 result = FALSE;
1783 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1784 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1785 ok(result, "Unexpected result %d.\n", result);
1788 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1789 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1791 result = TRUE;
1792 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1793 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1794 ok(!result, "Unexpected result %d.\n", result);
1796 result = TRUE;
1797 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1798 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1799 ok(!result, "Unexpected result %d.\n", result);
1801 result = FALSE;
1802 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1803 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1804 ok(result, "Unexpected result %d.\n", result);
1806 result = FALSE;
1807 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1808 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1809 ok(result, "Unexpected result %d.\n", result);
1811 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1812 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1814 result = TRUE;
1815 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1816 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1817 ok(!result, "Unexpected result %d.\n", result);
1819 result = TRUE;
1820 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1821 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1822 ok(!result, "Unexpected result %d.\n", result);
1824 result = TRUE;
1825 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1826 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1827 ok(!result, "Unexpected result %d.\n", result);
1829 result = TRUE;
1830 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1831 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1832 ok(!result, "Unexpected result %d.\n", result);
1834 result = TRUE;
1835 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1836 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1837 ok(!result, "Unexpected result %d.\n", result);
1839 result = TRUE;
1840 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1841 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1842 ok(!result, "Unexpected result %d.\n", result);
1844 result = TRUE;
1845 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1846 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1847 ok(!result, "Unexpected result %d.\n", result);
1849 result = TRUE;
1850 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1851 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1852 ok(!result, "Unexpected result %d.\n", result);
1854 result = TRUE;
1855 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1856 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1857 ok(!result, "Unexpected result %d.\n", result);
1859 result = TRUE;
1860 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1861 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1862 ok(!result, "Unexpected result %d.\n", result);
1864 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1865 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1867 result = FALSE;
1868 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1869 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1870 ok(result, "Unexpected result %d.\n", result);
1872 result = FALSE;
1873 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1874 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1875 ok(result, "Unexpected result %d.\n", result);
1877 result = FALSE;
1878 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1879 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1880 ok(result, "Unexpected result %d.\n", result);
1882 result = FALSE;
1883 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1884 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1885 ok(result, "Unexpected result %d.\n", result);
1887 result = FALSE;
1888 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1889 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1890 ok(result, "Unexpected result %d.\n", result);
1892 result = FALSE;
1893 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1894 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1895 ok(result, "Unexpected result %d.\n", result);
1897 result = FALSE;
1898 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1899 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1900 ok(result, "Unexpected result %d.\n", result);
1902 result = FALSE;
1903 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1904 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1905 ok(result, "Unexpected result %d.\n", result);
1907 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1908 ok(hr == S_OK, "Failed to set value, hr %#lx.\n", hr);
1910 result = TRUE;
1911 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1912 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1913 ok(!result, "Unexpected result %d.\n", result);
1915 result = TRUE;
1916 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1917 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1918 ok(!result, "Unexpected result %d.\n", result);
1920 result = FALSE;
1921 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1922 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1923 ok(result, "Unexpected result %d.\n", result);
1925 result = FALSE;
1926 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1927 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1928 ok(result, "Unexpected result %d.\n", result);
1930 result = FALSE;
1931 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1932 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1933 ok(result, "Unexpected result %d.\n", result);
1935 result = TRUE;
1936 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1937 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1938 ok(!result, "Unexpected result %d.\n", result);
1940 result = FALSE;
1941 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1942 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1943 ok(result, "Unexpected result %d.\n", result);
1945 result = TRUE;
1946 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1947 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1948 ok(!result, "Unexpected result %d.\n", result);
1950 result = FALSE;
1951 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1952 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1953 ok(result, "Unexpected result %d.\n", result);
1955 result = FALSE;
1956 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1957 ok(hr == S_OK, "Failed to compare, hr %#lx.\n", hr);
1958 ok(result, "Unexpected result %d.\n", result);
1960 IMFAttributes_Release(attributes);
1961 IMFAttributes_Release(attributes1);
1964 static void test_MFCreateMFByteStreamOnStream(void)
1966 IMFByteStream *bytestream;
1967 IMFByteStream *bytestream2;
1968 IStream *stream;
1969 IMFAttributes *attributes = NULL;
1970 DWORD caps, written;
1971 IUnknown *unknown;
1972 ULONG ref, size;
1973 HRESULT hr;
1974 UINT count;
1975 QWORD to;
1977 if(!pMFCreateMFByteStreamOnStream)
1979 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1980 return;
1983 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1984 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1986 caps = 0xffff0000;
1987 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1988 ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr);
1990 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1991 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1993 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1994 (void **)&unknown);
1995 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1996 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1997 ref = IUnknown_Release(unknown);
1998 ok(ref == 1, "got %lu\n", ref);
2000 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
2001 (void **)&bytestream2);
2002 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2003 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2004 ref = IMFByteStream_Release(bytestream2);
2005 ok(ref == 1, "got %lu\n", ref);
2007 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2008 (void **)&attributes);
2009 ok(hr == S_OK ||
2010 /* w7pro64 */
2011 broken(hr == E_NOINTERFACE), "Unexpected hr %#lx.\n", hr);
2013 if (hr != S_OK)
2015 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
2016 IStream_Release(stream);
2017 IMFByteStream_Release(bytestream);
2018 return;
2021 ok(attributes != NULL, "got NULL\n");
2022 hr = IMFAttributes_GetCount(attributes, &count);
2023 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2024 ok(count == 0, "Unexpected attributes count %u.\n", count);
2026 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
2027 (void **)&unknown);
2028 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2029 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2030 ref = IUnknown_Release(unknown);
2031 ok(ref == 2, "got %lu\n", ref);
2033 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
2034 (void **)&bytestream2);
2035 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2036 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2037 ref = IMFByteStream_Release(bytestream2);
2038 ok(ref == 2, "got %lu\n", ref);
2040 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2041 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2042 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2043 check_interface(bytestream, &IID_IMFGetService, FALSE);
2045 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2046 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2047 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2049 hr = IMFByteStream_Close(bytestream);
2050 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2052 hr = IMFByteStream_Close(bytestream);
2053 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2055 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2056 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2057 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2059 /* IMFByteStream maintains position separately from IStream */
2060 caps = 0;
2061 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2062 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2063 ok(size == 4, "Unexpected size.\n");
2064 ok(caps == 0xffff0000, "Unexpected content.\n");
2066 caps = 0;
2067 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2068 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2069 ok(size == 4, "Unexpected size.\n");
2070 ok(caps == 0xffff0000, "Unexpected content.\n");
2072 caps = 0;
2073 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2074 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2075 ok(size == 0, "Unexpected size.\n");
2076 ok(caps == 0, "Unexpected content.\n");
2078 hr = IMFByteStream_Seek(bytestream, msoBegin, 0, 0, &to);
2079 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2081 hr = IStream_Read(stream, &caps, sizeof(caps), &size);
2082 ok(hr == S_OK, "Failed to read from raw stream, hr %#lx.\n", hr);
2083 ok(size == 0, "Unexpected size.\n");
2084 ok(caps == 0, "Unexpected content.\n");
2086 caps = 0;
2087 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2088 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2089 ok(size == 4, "Unexpected size.\n");
2090 ok(caps == 0xffff0000, "Unexpected content.\n");
2092 caps = 0;
2093 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2094 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2095 ok(size == 0, "Unexpected size.\n");
2096 ok(caps == 0, "Unexpected content.\n");
2098 IMFAttributes_Release(attributes);
2099 IMFByteStream_Release(bytestream);
2100 IStream_Release(stream);
2103 static void test_file_stream(void)
2105 static const WCHAR newfilename[] = L"new.mp4";
2106 IMFByteStream *bytestream, *bytestream2;
2107 QWORD bytestream_length, position;
2108 IMFAttributes *attributes = NULL;
2109 MF_ATTRIBUTE_TYPE item_type;
2110 WCHAR pathW[MAX_PATH];
2111 WCHAR *filename;
2112 HRESULT hr;
2113 WCHAR *str;
2114 DWORD caps;
2115 UINT count;
2116 BOOL eos;
2118 filename = load_resource(L"test.mp4");
2120 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2121 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2123 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2124 MF_FILEFLAGS_NONE, filename, &bytestream);
2125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2127 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2128 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2129 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2130 check_interface(bytestream, &IID_IMFGetService, TRUE);
2132 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2133 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2134 if (is_win8_plus)
2136 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
2137 "Unexpected caps %#lx.\n", caps);
2139 else
2140 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2142 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2143 (void **)&attributes);
2144 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2145 ok(attributes != NULL, "got NULL\n");
2147 hr = IMFAttributes_GetCount(attributes, &count);
2148 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2149 ok(count == 2, "Unexpected attributes count %u.\n", count);
2151 /* Original file name. */
2152 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
2153 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
2154 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
2155 CoTaskMemFree(str);
2157 /* Modification time. */
2158 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
2159 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
2160 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
2162 IMFAttributes_Release(attributes);
2164 /* Length. */
2165 hr = IMFByteStream_GetLength(bytestream, NULL);
2166 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2168 bytestream_length = 0;
2169 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
2170 ok(hr == S_OK, "Failed to get bytestream length, hr %#lx.\n", hr);
2171 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
2173 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
2174 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2176 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
2177 ok(hr == S_OK, "Failed query end of stream, hr %#lx.\n", hr);
2178 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
2180 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
2181 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2183 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
2184 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2186 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
2187 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2188 ok(position == 2 * bytestream_length, "Unexpected position.\n");
2190 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2191 MF_FILEFLAGS_NONE, filename, &bytestream2);
2192 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2193 IMFByteStream_Release(bytestream2);
2195 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2196 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2198 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2199 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2201 IMFByteStream_Release(bytestream);
2203 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2204 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2205 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
2207 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2208 MF_FILEFLAGS_NONE, filename, &bytestream);
2209 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#lx.\n", hr);
2211 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2212 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2215 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2216 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2218 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2219 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2221 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2222 newfilename, &bytestream2);
2223 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2225 IMFByteStream_Release(bytestream);
2227 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2228 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
2229 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2231 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
2232 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2233 newfilename, &bytestream2);
2234 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2236 IMFByteStream_Release(bytestream);
2238 /* Explicit file: scheme */
2239 lstrcpyW(pathW, fileschemeW);
2240 lstrcatW(pathW, filename);
2241 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2242 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2244 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream);
2245 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2246 ok(DeleteFileW(filename), "failed to delete file\n");
2247 IMFByteStream_Release(bytestream);
2249 hr = MFShutdown();
2250 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2252 DeleteFileW(newfilename);
2255 static void test_system_memory_buffer(void)
2257 IMFMediaBuffer *buffer;
2258 HRESULT hr;
2259 DWORD length, max;
2260 BYTE *data, *data2;
2262 hr = MFCreateMemoryBuffer(1024, NULL);
2263 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2265 hr = MFCreateMemoryBuffer(0, &buffer);
2266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2267 if(buffer)
2269 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2270 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2271 ok(length == 0, "got %lu\n", length);
2273 IMFMediaBuffer_Release(buffer);
2276 hr = MFCreateMemoryBuffer(1024, &buffer);
2277 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2279 check_interface(buffer, &IID_IMFGetService, FALSE);
2281 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2282 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2284 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2286 ok(length == 1024, "got %lu\n", length);
2288 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2289 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2291 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2294 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2295 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2297 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2299 ok(length == 10, "got %lu\n", length);
2301 length = 0;
2302 max = 0;
2303 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2304 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2305 ok(length == 0, "got %lu\n", length);
2306 ok(max == 0, "got %lu\n", length);
2308 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2309 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2310 ok(length == 10, "got %lu\n", length);
2311 ok(max == 1024, "got %lu\n", max);
2313 /* Attempt to lock the buffer twice */
2314 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2315 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2316 ok(data == data2, "Unexpected hr %#lx.\n", hr);
2318 hr = IMFMediaBuffer_Unlock(buffer);
2319 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2321 hr = IMFMediaBuffer_Unlock(buffer);
2322 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2324 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2327 hr = IMFMediaBuffer_Unlock(buffer);
2328 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2330 /* Extra Unlock */
2331 hr = IMFMediaBuffer_Unlock(buffer);
2332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2334 IMFMediaBuffer_Release(buffer);
2337 static void test_system_memory_aligned_buffer(void)
2339 static const DWORD alignments[] =
2341 MF_16_BYTE_ALIGNMENT,
2342 MF_32_BYTE_ALIGNMENT,
2343 MF_64_BYTE_ALIGNMENT,
2344 MF_128_BYTE_ALIGNMENT,
2345 MF_256_BYTE_ALIGNMENT,
2346 MF_512_BYTE_ALIGNMENT,
2348 IMFMediaBuffer *buffer;
2349 DWORD length, max;
2350 unsigned int i;
2351 BYTE *data;
2352 HRESULT hr;
2354 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2355 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2357 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2358 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2360 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2361 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2362 ok(length == 0, "Unexpected current length %lu.\n", length);
2364 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2365 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2366 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2367 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2368 ok(length == 1, "Unexpected current length %lu.\n", length);
2370 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2371 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2372 ok(length == 201, "Unexpected max length %lu.\n", length);
2374 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2375 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2376 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2377 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2378 ok(length == 201, "Unexpected max length %lu.\n", length);
2379 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2380 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2382 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2383 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2384 ok(max == 201 && length == 10, "Unexpected length.\n");
2385 hr = IMFMediaBuffer_Unlock(buffer);
2386 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2388 IMFMediaBuffer_Release(buffer);
2390 for (i = 0; i < ARRAY_SIZE(alignments); ++i)
2392 hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
2393 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2395 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2396 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2397 ok(max == 200 && !length, "Unexpected length.\n");
2398 ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
2399 hr = IMFMediaBuffer_Unlock(buffer);
2400 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2402 IMFMediaBuffer_Release(buffer);
2405 hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
2406 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2407 IMFMediaBuffer_Release(buffer);
2410 static void test_sample(void)
2412 static const DWORD test_pattern = 0x22222222;
2413 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2414 DWORD count, flags, length;
2415 IMFAttributes *attributes;
2416 IMFSample *sample;
2417 LONGLONG time;
2418 HRESULT hr;
2419 BYTE *data;
2421 hr = MFCreateSample( &sample );
2422 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2424 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2425 ok(hr == S_OK, "Failed to get attributes interface, hr %#lx.\n", hr);
2427 CHECK_ATTR_COUNT(attributes, 0);
2429 hr = IMFSample_GetBufferCount(sample, NULL);
2430 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2432 hr = IMFSample_GetBufferCount(sample, &count);
2433 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2434 ok(count == 0, "got %ld\n", count);
2436 hr = IMFSample_GetSampleFlags(sample, &flags);
2437 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2438 ok(!flags, "Unexpected flags %#lx.\n", flags);
2440 hr = IMFSample_SetSampleFlags(sample, 0x123);
2441 ok(hr == S_OK, "Failed to set sample flags, hr %#lx.\n", hr);
2442 hr = IMFSample_GetSampleFlags(sample, &flags);
2443 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2444 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
2446 hr = IMFSample_GetSampleTime(sample, &time);
2447 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
2449 hr = IMFSample_GetSampleDuration(sample, &time);
2450 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
2452 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2453 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2455 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2456 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2458 hr = IMFSample_RemoveAllBuffers(sample);
2459 ok(hr == S_OK, "Failed to remove all, hr %#lx.\n", hr);
2461 hr = IMFSample_GetTotalLength(sample, &length);
2462 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2463 ok(!length, "Unexpected total length %lu.\n", length);
2465 hr = MFCreateMemoryBuffer(16, &buffer);
2466 ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
2468 hr = IMFSample_AddBuffer(sample, buffer);
2469 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2471 hr = IMFSample_AddBuffer(sample, buffer);
2472 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2474 hr = IMFSample_GetBufferCount(sample, &count);
2475 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2476 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2478 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2479 ok(hr == S_OK, "Failed to get buffer, hr %#lx.\n", hr);
2480 ok(buffer2 == buffer, "Unexpected object.\n");
2481 IMFMediaBuffer_Release(buffer2);
2483 hr = IMFSample_GetTotalLength(sample, &length);
2484 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2485 ok(!length, "Unexpected total length %lu.\n", length);
2487 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2488 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2490 hr = IMFSample_GetTotalLength(sample, &length);
2491 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2492 ok(length == 4, "Unexpected total length %lu.\n", length);
2494 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2495 ok(hr == S_OK, "Failed to remove buffer, hr %#lx.\n", hr);
2497 hr = IMFSample_GetTotalLength(sample, &length);
2498 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2499 ok(length == 2, "Unexpected total length %lu.\n", length);
2501 IMFMediaBuffer_Release(buffer);
2503 /* Duration */
2504 hr = IMFSample_SetSampleDuration(sample, 10);
2505 ok(hr == S_OK, "Failed to set duration, hr %#lx.\n", hr);
2506 CHECK_ATTR_COUNT(attributes, 0);
2507 hr = IMFSample_GetSampleDuration(sample, &time);
2508 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
2509 ok(time == 10, "Unexpected duration.\n");
2511 /* Timestamp */
2512 hr = IMFSample_SetSampleTime(sample, 1);
2513 ok(hr == S_OK, "Failed to set timestamp, hr %#lx.\n", hr);
2514 CHECK_ATTR_COUNT(attributes, 0);
2515 hr = IMFSample_GetSampleTime(sample, &time);
2516 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
2517 ok(time == 1, "Unexpected timestamp.\n");
2519 IMFAttributes_Release(attributes);
2520 IMFSample_Release(sample);
2522 /* CopyToBuffer() */
2523 hr = MFCreateSample(&sample);
2524 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2526 hr = MFCreateMemoryBuffer(16, &buffer2);
2527 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2529 /* Sample with no buffers. */
2530 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2531 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2532 hr = IMFSample_CopyToBuffer(sample, buffer2);
2533 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2534 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2535 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2536 ok(!length, "Unexpected length %lu.\n", length);
2538 /* Single buffer, larger destination. */
2539 hr = MFCreateMemoryBuffer(8, &buffer);
2540 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2542 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2543 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2544 *(DWORD *)data = 0x11111111;
2545 hr = IMFMediaBuffer_Unlock(buffer);
2546 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2547 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2548 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2550 hr = IMFSample_AddBuffer(sample, buffer);
2551 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2553 /* Existing content is overwritten. */
2554 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2555 ok(hr == S_OK, "Failed to set length, hr %#lx.\n", hr);
2557 hr = IMFSample_CopyToBuffer(sample, buffer2);
2558 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2560 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2561 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2562 ok(length == 4, "Unexpected buffer length %lu.\n", length);
2564 /* Multiple buffers, matching total size. */
2565 hr = IMFSample_AddBuffer(sample, buffer);
2566 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2568 hr = IMFSample_GetBufferCount(sample, &count);
2569 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2570 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2572 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2573 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2575 hr = IMFSample_CopyToBuffer(sample, buffer2);
2576 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2578 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2579 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2580 ok(length == 16, "Unexpected buffer length %lu.\n", length);
2582 hr = IMFSample_AddBuffer(sample, buffer);
2583 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2585 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2586 ok(hr == S_OK, "Failed to set buffer length, hr %#lx.\n", hr);
2588 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2589 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2590 *(DWORD *)data = test_pattern;
2591 hr = IMFMediaBuffer_Unlock(buffer2);
2592 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2594 hr = IMFSample_CopyToBuffer(sample, buffer2);
2595 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
2597 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2598 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2599 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#lx\n", *(DWORD *)data);
2600 hr = IMFMediaBuffer_Unlock(buffer2);
2601 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2603 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2604 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2605 ok(!length, "Unexpected buffer length %lu.\n", length);
2607 IMFMediaBuffer_Release(buffer2);
2608 IMFSample_Release(sample);
2610 /* ConvertToContiguousBuffer() */
2611 hr = MFCreateSample(&sample);
2612 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2614 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2615 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2617 hr = MFCreateMemoryBuffer(16, &buffer);
2618 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2620 hr = IMFSample_AddBuffer(sample, buffer);
2621 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2623 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2624 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2625 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2626 IMFMediaBuffer_Release(buffer2);
2628 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2629 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2631 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2632 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2633 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2634 IMFMediaBuffer_Release(buffer2);
2636 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2637 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2639 hr = MFCreateMemoryBuffer(16, &buffer2);
2640 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2642 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2643 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2645 hr = IMFSample_AddBuffer(sample, buffer2);
2646 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2647 IMFMediaBuffer_Release(buffer2);
2649 hr = IMFSample_GetBufferCount(sample, &count);
2650 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2651 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2653 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2654 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2656 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2657 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2658 ok(length == 7, "Unexpected length %lu.\n", length);
2660 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2661 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2662 ok(length == 7, "Unexpected length %lu.\n", length);
2664 IMFMediaBuffer_Release(buffer3);
2666 hr = IMFSample_GetBufferCount(sample, &count);
2667 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2668 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2670 hr = IMFSample_AddBuffer(sample, buffer);
2671 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2673 hr = IMFSample_GetBufferCount(sample, &count);
2674 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2675 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2677 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2678 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2680 hr = IMFSample_GetBufferCount(sample, &count);
2681 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2682 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2684 IMFMediaBuffer_Release(buffer);
2686 IMFSample_Release(sample);
2689 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2691 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2692 IMFMediaEventQueue *queue;
2693 IUnknown *state, *obj;
2694 HRESULT hr;
2696 ok(result != NULL, "Unexpected result object.\n");
2698 state = IMFAsyncResult_GetStateNoAddRef(result);
2699 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2701 IMFMediaEvent *event = NULL, *event2;
2703 if (is_win8_plus)
2705 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2706 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2708 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2709 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2711 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2712 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#lx.\n", hr);
2714 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2715 ok(hr == E_FAIL, "Unexpected result, hr %#lx.\n", hr);
2717 if (event)
2718 IMFMediaEvent_Release(event);
2721 hr = IMFAsyncResult_GetObject(result, &obj);
2722 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2724 IMFMediaEventQueue_Release(queue);
2726 SetEvent(callback->event);
2729 return E_NOTIMPL;
2732 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2734 testcallback_QueryInterface,
2735 testcallback_AddRef,
2736 testcallback_Release,
2737 testcallback_GetParameters,
2738 testcallback_Invoke,
2741 static void test_MFCreateAsyncResult(void)
2743 IMFAsyncResult *result, *result2;
2744 struct test_callback *callback;
2745 IUnknown *state, *object;
2746 MFASYNCRESULT *data;
2747 ULONG refcount;
2748 HANDLE event;
2749 DWORD flags;
2750 HRESULT hr;
2751 BOOL ret;
2753 callback = create_test_callback(NULL);
2755 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2756 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2758 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2759 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2761 data = (MFASYNCRESULT *)result;
2762 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2763 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2764 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2765 ok(data->hEvent == NULL, "Unexpected event.\n");
2767 hr = IMFAsyncResult_GetState(result, NULL);
2768 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2770 state = (void *)0xdeadbeef;
2771 hr = IMFAsyncResult_GetState(result, &state);
2772 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2773 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2775 hr = IMFAsyncResult_GetStatus(result);
2776 ok(hr == S_OK, "Unexpected status %#lx.\n", hr);
2778 data->hrStatusResult = 123;
2779 hr = IMFAsyncResult_GetStatus(result);
2780 ok(hr == 123, "Unexpected status %#lx.\n", hr);
2782 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2783 ok(hr == S_OK, "Failed to set status, hr %#lx.\n", hr);
2784 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#lx.\n", hr);
2786 hr = IMFAsyncResult_GetObject(result, NULL);
2787 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2789 object = (void *)0xdeadbeef;
2790 hr = IMFAsyncResult_GetObject(result, &object);
2791 ok(hr == E_POINTER, "Failed to get object, hr %#lx.\n", hr);
2792 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2794 state = IMFAsyncResult_GetStateNoAddRef(result);
2795 ok(state == NULL, "Unexpected state.\n");
2797 /* Object. */
2798 hr = MFCreateAsyncResult((IUnknown *)result, &callback->IMFAsyncCallback_iface, NULL, &result2);
2799 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2801 data = (MFASYNCRESULT *)result2;
2802 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2803 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2804 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2805 ok(data->hEvent == NULL, "Unexpected event.\n");
2807 object = NULL;
2808 hr = IMFAsyncResult_GetObject(result2, &object);
2809 ok(hr == S_OK, "Failed to get object, hr %#lx.\n", hr);
2810 ok(object == (IUnknown *)result, "Unexpected object.\n");
2811 IUnknown_Release(object);
2813 IMFAsyncResult_Release(result2);
2815 /* State object. */
2816 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2817 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2819 data = (MFASYNCRESULT *)result2;
2820 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2821 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2822 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2823 ok(data->hEvent == NULL, "Unexpected event.\n");
2825 state = NULL;
2826 hr = IMFAsyncResult_GetState(result2, &state);
2827 ok(hr == S_OK, "Failed to get state object, hr %#lx.\n", hr);
2828 ok(state == (IUnknown *)result, "Unexpected state.\n");
2829 IUnknown_Release(state);
2831 state = IMFAsyncResult_GetStateNoAddRef(result2);
2832 ok(state == (IUnknown *)result, "Unexpected state.\n");
2834 refcount = IMFAsyncResult_Release(result2);
2835 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2836 refcount = IMFAsyncResult_Release(result);
2837 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2839 /* Event handle is closed on release. */
2840 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2841 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2843 data = (MFASYNCRESULT *)result;
2844 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2845 ok(data->hEvent != NULL, "Failed to create event.\n");
2846 ret = GetHandleInformation(event, &flags);
2847 ok(ret, "Failed to get handle info.\n");
2849 refcount = IMFAsyncResult_Release(result);
2850 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2851 ret = GetHandleInformation(event, &flags);
2852 ok(!ret, "Expected handle to be closed.\n");
2854 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
2855 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2857 data = (MFASYNCRESULT *)result;
2858 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2859 ok(data->hEvent != NULL, "Failed to create event.\n");
2860 ret = GetHandleInformation(event, &flags);
2861 ok(ret, "Failed to get handle info.\n");
2863 refcount = IMFAsyncResult_Release(result);
2864 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2865 ret = GetHandleInformation(event, &flags);
2866 ok(!ret, "Expected handle to be closed.\n");
2868 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
2871 static void test_startup(void)
2873 DWORD queue;
2874 HRESULT hr;
2876 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2877 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#lx.\n", hr);
2879 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2880 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2882 hr = MFAllocateWorkQueue(&queue);
2883 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2884 hr = MFUnlockWorkQueue(queue);
2885 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2887 hr = MFShutdown();
2888 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2890 hr = MFAllocateWorkQueue(&queue);
2891 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2893 /* Already shut down, has no effect. */
2894 hr = MFShutdown();
2895 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2897 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2898 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2900 hr = MFAllocateWorkQueue(&queue);
2901 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2902 hr = MFUnlockWorkQueue(queue);
2903 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2905 hr = MFShutdown();
2906 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2908 /* Platform lock. */
2909 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2910 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2912 hr = MFAllocateWorkQueue(&queue);
2913 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2914 hr = MFUnlockWorkQueue(queue);
2915 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2917 /* Unlocking implies shutdown. */
2918 hr = MFUnlockPlatform();
2919 ok(hr == S_OK, "Failed to unlock, %#lx.\n", hr);
2921 hr = MFAllocateWorkQueue(&queue);
2922 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2924 hr = MFLockPlatform();
2925 ok(hr == S_OK, "Failed to lock, %#lx.\n", hr);
2927 hr = MFAllocateWorkQueue(&queue);
2928 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2929 hr = MFUnlockWorkQueue(queue);
2930 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2932 hr = MFShutdown();
2933 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2936 static void test_allocate_queue(void)
2938 DWORD queue, queue2;
2939 HRESULT hr;
2941 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2942 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2944 hr = MFAllocateWorkQueue(&queue);
2945 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2946 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2948 hr = MFUnlockWorkQueue(queue);
2949 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2951 hr = MFUnlockWorkQueue(queue);
2952 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2954 hr = MFAllocateWorkQueue(&queue2);
2955 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2956 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2958 hr = MFUnlockWorkQueue(queue2);
2959 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2961 /* Unlock in system queue range. */
2962 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2963 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2965 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2966 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2968 hr = MFUnlockWorkQueue(0x20);
2969 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2971 hr = MFShutdown();
2972 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2975 static void test_MFCopyImage(void)
2977 BYTE dest[16], src[16];
2978 HRESULT hr;
2980 if (!pMFCopyImage)
2982 win_skip("MFCopyImage() is not available.\n");
2983 return;
2986 memset(dest, 0xaa, sizeof(dest));
2987 memset(src, 0x11, sizeof(src));
2989 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2990 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
2991 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2993 memset(dest, 0xaa, sizeof(dest));
2994 memset(src, 0x11, sizeof(src));
2996 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2997 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
2998 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3000 memset(dest, 0xaa, sizeof(dest));
3001 memset(src, 0x11, sizeof(src));
3003 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
3004 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
3005 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
3008 static void test_MFCreateCollection(void)
3010 IMFCollection *collection;
3011 IUnknown *element;
3012 DWORD count;
3013 HRESULT hr;
3015 hr = MFCreateCollection(NULL);
3016 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3018 hr = MFCreateCollection(&collection);
3019 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
3021 hr = IMFCollection_GetElementCount(collection, NULL);
3022 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3024 count = 1;
3025 hr = IMFCollection_GetElementCount(collection, &count);
3026 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3027 ok(count == 0, "Unexpected count %lu.\n", count);
3029 hr = IMFCollection_GetElement(collection, 0, NULL);
3030 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3032 element = (void *)0xdeadbeef;
3033 hr = IMFCollection_GetElement(collection, 0, &element);
3034 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3035 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3037 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3038 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3040 element = (void *)0xdeadbeef;
3041 hr = IMFCollection_RemoveElement(collection, 0, &element);
3042 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3043 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3045 hr = IMFCollection_RemoveAllElements(collection);
3046 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3048 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3049 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3051 count = 0;
3052 hr = IMFCollection_GetElementCount(collection, &count);
3053 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3054 ok(count == 1, "Unexpected count %lu.\n", count);
3056 hr = IMFCollection_AddElement(collection, NULL);
3057 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3059 count = 0;
3060 hr = IMFCollection_GetElementCount(collection, &count);
3061 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3062 ok(count == 2, "Unexpected count %lu.\n", count);
3064 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3065 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3067 count = 0;
3068 hr = IMFCollection_GetElementCount(collection, &count);
3069 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3070 ok(count == 11, "Unexpected count %lu.\n", count);
3072 hr = IMFCollection_GetElement(collection, 0, &element);
3073 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3074 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3075 IUnknown_Release(element);
3077 hr = IMFCollection_GetElement(collection, 1, &element);
3078 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3079 ok(!element, "Unexpected element.\n");
3081 hr = IMFCollection_GetElement(collection, 2, &element);
3082 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3083 ok(!element, "Unexpected element.\n");
3085 hr = IMFCollection_GetElement(collection, 10, &element);
3086 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3087 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3088 IUnknown_Release(element);
3090 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3091 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3093 hr = IMFCollection_GetElement(collection, 0, &element);
3094 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3096 hr = IMFCollection_RemoveAllElements(collection);
3097 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3099 count = 1;
3100 hr = IMFCollection_GetElementCount(collection, &count);
3101 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3102 ok(count == 0, "Unexpected count %lu.\n", count);
3104 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3105 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3107 IMFCollection_Release(collection);
3110 static void test_MFHeapAlloc(void)
3112 void *res;
3114 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3115 ok(res != NULL, "MFHeapAlloc failed.\n");
3117 MFHeapFree(res);
3120 static void test_scheduled_items(void)
3122 struct test_callback *callback;
3123 IMFAsyncResult *result;
3124 MFWORKITEM_KEY key, key2;
3125 HRESULT hr;
3127 callback = create_test_callback(NULL);
3129 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3130 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3132 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3133 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3135 hr = MFCancelWorkItem(key);
3136 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3138 hr = MFCancelWorkItem(key);
3139 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3141 if (!pMFPutWaitingWorkItem)
3143 win_skip("Waiting items are not supported.\n");
3144 return;
3147 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3148 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3150 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3151 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3153 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3154 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3156 hr = MFCancelWorkItem(key);
3157 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3159 hr = MFCancelWorkItem(key2);
3160 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3162 IMFAsyncResult_Release(result);
3164 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3165 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3167 hr = MFCancelWorkItem(key);
3168 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3170 hr = MFShutdown();
3171 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3173 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3176 static void test_serial_queue(void)
3178 static const DWORD queue_ids[] =
3180 MFASYNC_CALLBACK_QUEUE_STANDARD,
3181 MFASYNC_CALLBACK_QUEUE_RT,
3182 MFASYNC_CALLBACK_QUEUE_IO,
3183 MFASYNC_CALLBACK_QUEUE_TIMER,
3184 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3185 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3187 DWORD queue, serial_queue;
3188 unsigned int i;
3189 HRESULT hr;
3191 if (!pMFAllocateSerialWorkQueue)
3193 win_skip("Serial queues are not supported.\n");
3194 return;
3197 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3198 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3200 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3202 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3203 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3205 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3206 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3207 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3209 if (SUCCEEDED(hr))
3211 hr = MFUnlockWorkQueue(serial_queue);
3212 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3216 /* Chain them together. */
3217 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3218 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3220 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3221 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3223 hr = MFUnlockWorkQueue(serial_queue);
3224 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3226 hr = MFUnlockWorkQueue(queue);
3227 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3229 hr = MFShutdown();
3230 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3233 static LONG periodic_counter;
3234 static void CALLBACK periodic_callback(IUnknown *context)
3236 InterlockedIncrement(&periodic_counter);
3239 static void test_periodic_callback(void)
3241 DWORD period, key;
3242 HRESULT hr;
3244 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3245 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3247 period = 0;
3248 hr = MFGetTimerPeriodicity(&period);
3249 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3250 ok(period == 10, "Unexpected period %lu.\n", period);
3252 if (!pMFAddPeriodicCallback)
3254 win_skip("Periodic callbacks are not supported.\n");
3255 hr = MFShutdown();
3256 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3257 return;
3260 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3262 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3263 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3264 ok(key != 0, "Unexpected key %#lx.\n", key);
3266 Sleep(10 * period);
3268 hr = pMFRemovePeriodicCallback(key);
3269 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3271 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3273 hr = MFShutdown();
3274 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3277 static void test_event_queue(void)
3279 struct test_callback *callback, *callback2;
3280 IMFMediaEvent *event, *event2;
3281 IMFMediaEventQueue *queue;
3282 IMFAsyncResult *result;
3283 HRESULT hr;
3284 DWORD ret;
3286 callback = create_test_callback(NULL);
3287 callback2 = create_test_callback(NULL);
3289 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3290 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3292 hr = MFCreateEventQueue(&queue);
3293 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3295 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3296 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3298 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3299 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3301 if (is_win8_plus)
3303 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3304 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3306 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3307 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3308 ok(event2 == event, "Unexpected event object.\n");
3309 IMFMediaEvent_Release(event2);
3311 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3312 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3314 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3315 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3316 IMFMediaEvent_Release(event2);
3319 /* Async case. */
3320 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3321 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3323 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3324 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3326 /* Same callback, same state. */
3327 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3328 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3330 /* Same callback, different state. */
3331 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3332 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3334 /* Different callback, same state. */
3335 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3336 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3338 /* Different callback, different state. */
3339 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3340 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3342 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
3344 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3345 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3347 ret = WaitForSingleObject(callback->event, 500);
3348 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3350 CloseHandle(callback->event);
3352 IMFMediaEvent_Release(event);
3354 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3355 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3357 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3358 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3360 /* Shutdown behavior. */
3361 hr = IMFMediaEventQueue_Shutdown(queue);
3362 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3364 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3365 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3367 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3368 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3369 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3370 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3371 IMFMediaEvent_Release(event);
3373 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3374 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3376 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3377 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3379 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3380 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3382 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3383 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3385 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3386 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3387 IMFAsyncResult_Release(result);
3389 /* Already shut down. */
3390 hr = IMFMediaEventQueue_Shutdown(queue);
3391 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3393 IMFMediaEventQueue_Release(queue);
3394 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3396 /* Release while subscribed. */
3397 callback = create_test_callback(NULL);
3399 hr = MFCreateEventQueue(&queue);
3400 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3402 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3403 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3404 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3406 IMFMediaEventQueue_Release(queue);
3407 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3408 ok(ret == 1 || broken(ret == 2) /* Vista */,
3409 "Unexpected refcount %ld, expected 1.\n", ret);
3410 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3412 hr = MFShutdown();
3413 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3416 static void test_presentation_descriptor(void)
3418 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3419 IMFPresentationDescriptor *pd, *pd2;
3420 IMFMediaType *media_type;
3421 unsigned int i;
3422 BOOL selected;
3423 UINT64 value;
3424 DWORD count;
3425 HRESULT hr;
3427 hr = MFCreateMediaType(&media_type);
3428 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3430 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3432 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3433 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3436 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3437 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3439 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3440 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3442 for (i = 0; i < count; ++i)
3444 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3445 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3446 ok(!selected, "Unexpected selected state.\n");
3447 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3448 IMFStreamDescriptor_Release(stream_desc2);
3451 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3452 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3454 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3455 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3457 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3458 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3460 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3461 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3462 ok(!!selected, "Unexpected selected state.\n");
3463 IMFStreamDescriptor_Release(stream_desc2);
3465 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3466 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3468 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3469 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3471 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3472 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3473 ok(!!selected, "Unexpected selected state.\n");
3474 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3475 IMFStreamDescriptor_Release(stream_desc2);
3477 value = 0;
3478 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3479 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3480 ok(value == 1, "Unexpected attribute value.\n");
3482 IMFPresentationDescriptor_Release(pd2);
3483 IMFPresentationDescriptor_Release(pd);
3485 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3487 IMFStreamDescriptor_Release(stream_desc[i]);
3490 /* Partially initialized array. */
3491 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3492 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3493 stream_desc[0] = NULL;
3495 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3496 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3498 IMFStreamDescriptor_Release(stream_desc[1]);
3499 IMFMediaType_Release(media_type);
3502 enum clock_action
3504 CLOCK_START,
3505 CLOCK_STOP,
3506 CLOCK_PAUSE,
3507 CLOCK_RESTART,
3510 static void test_system_time_source(void)
3512 static const struct clock_state_test
3514 enum clock_action action;
3515 MFCLOCK_STATE state;
3516 BOOL is_invalid;
3518 clock_state_change[] =
3520 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3521 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3522 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3523 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3524 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3525 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3526 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3527 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3528 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3529 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3530 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3531 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3532 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3533 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3534 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3535 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3536 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3538 IMFPresentationTimeSource *time_source, *time_source2;
3539 IMFClockStateSink *statesink;
3540 IMFClock *clock, *clock2;
3541 MFCLOCK_PROPERTIES props;
3542 MFCLOCK_STATE state;
3543 unsigned int i;
3544 MFTIME systime;
3545 LONGLONG time;
3546 DWORD value;
3547 HRESULT hr;
3549 hr = MFCreateSystemTimeSource(&time_source);
3550 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3552 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3553 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3554 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3555 "Unexpected flags %#lx.\n", value);
3557 value = 1;
3558 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3560 ok(value == 0, "Unexpected value %lu.\n", value);
3562 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3563 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3564 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3566 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3567 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
3569 /* State changes. */
3570 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3572 switch (clock_state_change[i].action)
3574 case CLOCK_STOP:
3575 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3576 break;
3577 case CLOCK_RESTART:
3578 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3579 break;
3580 case CLOCK_PAUSE:
3581 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3582 break;
3583 case CLOCK_START:
3584 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3585 break;
3586 default:
3589 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
3590 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3591 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
3592 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3595 IMFClockStateSink_Release(statesink);
3597 /* Properties. */
3598 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3599 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3601 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3602 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3604 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3605 wine_dbgstr_longlong(props.qwCorrelationRate));
3606 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3607 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3608 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3609 wine_dbgstr_longlong(props.qwClockFrequency));
3610 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3611 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3613 /* Underlying clock. */
3614 hr = MFCreateSystemTimeSource(&time_source2);
3615 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3616 EXPECT_REF(time_source2, 1);
3617 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3618 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3619 EXPECT_REF(time_source2, 1);
3620 EXPECT_REF(clock2, 2);
3622 EXPECT_REF(time_source, 1);
3623 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3624 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3625 EXPECT_REF(time_source, 1);
3626 EXPECT_REF(clock, 2);
3628 ok(clock != clock2, "Unexpected clock instance.\n");
3630 IMFPresentationTimeSource_Release(time_source2);
3631 IMFClock_Release(clock2);
3633 hr = IMFClock_GetClockCharacteristics(clock, &value);
3634 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
3635 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3636 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
3638 hr = IMFClock_GetContinuityKey(clock, &value);
3639 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
3640 ok(value == 0, "Unexpected key value %lu.\n", value);
3642 hr = IMFClock_GetState(clock, 0, &state);
3643 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
3644 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3646 hr = IMFClock_GetProperties(clock, &props);
3647 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3649 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3650 wine_dbgstr_longlong(props.qwCorrelationRate));
3651 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3652 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3653 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3654 wine_dbgstr_longlong(props.qwClockFrequency));
3655 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3656 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3658 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3659 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
3660 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3662 IMFClock_Release(clock);
3664 /* Test returned time regarding specified rate and offset. */
3665 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3666 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3668 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3669 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
3670 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3672 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3673 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3674 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3676 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3677 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3679 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3680 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3681 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3683 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3684 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3686 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3687 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3688 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3689 wine_dbgstr_longlong(systime));
3691 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3692 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3694 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3695 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3696 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3698 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3699 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3701 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3702 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3703 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3704 wine_dbgstr_longlong(systime));
3706 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3707 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3709 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3710 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3711 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3712 wine_dbgstr_longlong(systime));
3714 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3715 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3717 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3718 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3719 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3721 /* Increased rate. */
3722 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3723 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3725 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3726 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3728 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
3729 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3731 hr = IMFClockStateSink_OnClockPause(statesink, 6);
3732 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3734 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3735 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3736 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3737 wine_dbgstr_longlong(systime));
3739 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
3740 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3742 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3743 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3745 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3746 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3747 ok(time == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3748 wine_dbgstr_longlong(systime));
3750 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3751 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3753 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3754 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3755 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3756 wine_dbgstr_longlong(2 * systime));
3758 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3759 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3761 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3762 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3763 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3764 wine_dbgstr_longlong(2 * systime));
3766 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3767 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3769 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3770 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3771 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3772 wine_dbgstr_longlong(systime));
3774 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3775 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3777 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3778 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3779 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3780 wine_dbgstr_longlong(systime));
3782 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3783 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3785 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3786 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3787 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3788 wine_dbgstr_longlong(systime));
3790 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3791 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3793 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3794 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3795 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3797 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3798 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3800 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3801 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3802 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3803 wine_dbgstr_longlong(2 * systime));
3805 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3806 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3808 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3809 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3811 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3812 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3813 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3814 wine_dbgstr_longlong(2 * systime));
3816 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3817 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3819 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3820 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3821 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3822 wine_dbgstr_longlong(systime));
3824 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3825 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3827 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3828 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3829 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3830 wine_dbgstr_longlong(systime));
3832 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3833 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3835 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3836 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3837 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3838 wine_dbgstr_longlong(systime));
3840 IMFClockStateSink_Release(statesink);
3841 IMFPresentationTimeSource_Release(time_source);
3843 /* PRESENTATION_CURRENT_POSITION */
3844 hr = MFCreateSystemTimeSource(&time_source);
3845 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3847 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3848 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3850 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3851 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3852 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3853 wine_dbgstr_longlong(systime));
3855 /* INVALID -> RUNNING */
3856 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3857 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3859 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3860 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3861 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3862 wine_dbgstr_longlong(systime));
3864 /* RUNNING -> RUNNING */
3865 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3866 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3868 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3869 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3870 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3871 wine_dbgstr_longlong(systime));
3873 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3874 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3876 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3877 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3878 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3879 wine_dbgstr_longlong(systime));
3881 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3882 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3884 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3885 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3886 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3887 wine_dbgstr_longlong(systime));
3889 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3890 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3892 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3893 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3894 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3895 wine_dbgstr_longlong(systime));
3897 /* STOPPED -> RUNNING */
3898 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3899 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3901 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3902 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3903 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3904 wine_dbgstr_longlong(systime));
3906 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3907 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3909 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3910 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3911 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3912 wine_dbgstr_longlong(systime));
3914 /* PAUSED -> RUNNING */
3915 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3916 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3918 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3919 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3920 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3921 wine_dbgstr_longlong(systime));
3923 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3924 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3926 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3927 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3928 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3929 wine_dbgstr_longlong(systime));
3931 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3932 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3934 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3935 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3936 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3937 wine_dbgstr_longlong(systime));
3939 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3940 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3942 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3943 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3944 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3945 wine_dbgstr_longlong(systime));
3947 IMFClockStateSink_Release(statesink);
3948 IMFPresentationTimeSource_Release(time_source);
3951 static void test_MFInvokeCallback(void)
3953 struct test_callback *callback;
3954 IMFAsyncResult *result;
3955 MFASYNCRESULT *data;
3956 ULONG refcount;
3957 HRESULT hr;
3958 DWORD ret;
3960 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3961 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3963 callback = create_test_callback(NULL);
3965 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3966 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3968 data = (MFASYNCRESULT *)result;
3969 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3970 ok(data->hEvent != NULL, "Failed to create event.\n");
3972 hr = MFInvokeCallback(result);
3973 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
3975 ret = WaitForSingleObject(data->hEvent, 100);
3976 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
3978 refcount = IMFAsyncResult_Release(result);
3979 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3981 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3983 hr = MFShutdown();
3984 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3987 static void test_stream_descriptor(void)
3989 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3990 IMFMediaTypeHandler *type_handler;
3991 IMFStreamDescriptor *stream_desc;
3992 GUID major_type;
3993 DWORD id, count;
3994 unsigned int i;
3995 HRESULT hr;
3997 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3998 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4000 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4002 hr = MFCreateMediaType(&media_types[i]);
4003 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4006 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
4007 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4009 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4010 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4012 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
4013 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
4014 ok(id == 123, "Unexpected id %#lx.\n", id);
4016 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4017 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4019 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4020 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4021 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4023 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
4024 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
4026 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4027 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4029 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
4031 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
4032 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
4033 ok(media_type == media_types[i], "Unexpected object.\n");
4035 if (SUCCEEDED(hr))
4036 IMFMediaType_Release(media_type);
4039 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4040 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4042 /* IsMediaTypeSupported() */
4044 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4045 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4047 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4048 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4050 hr = MFCreateMediaType(&media_type);
4051 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4053 hr = MFCreateMediaType(&media_type3);
4054 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4056 media_type2 = (void *)0xdeadbeef;
4057 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4058 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4059 ok(!media_type2, "Unexpected pointer.\n");
4061 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4062 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4064 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4065 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4067 media_type2 = (void *)0xdeadbeef;
4068 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4069 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4070 ok(!media_type2, "Unexpected pointer.\n");
4072 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4073 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4075 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4076 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4078 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4079 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4080 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4082 /* Mismatching major types. */
4083 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4084 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4086 media_type2 = (void *)0xdeadbeef;
4087 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4088 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4089 ok(!media_type2, "Unexpected pointer.\n");
4091 /* Subtype missing. */
4092 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4093 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4095 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4096 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4098 media_type2 = (void *)0xdeadbeef;
4099 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4100 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4101 ok(!media_type2, "Unexpected pointer.\n");
4103 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4104 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4106 media_type2 = (void *)0xdeadbeef;
4107 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4108 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4109 ok(!media_type2, "Unexpected pointer.\n");
4111 /* Mismatching subtype. */
4112 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4113 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4115 media_type2 = (void *)0xdeadbeef;
4116 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4117 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4118 ok(!media_type2, "Unexpected pointer.\n");
4120 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4121 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4122 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4124 IMFMediaTypeHandler_Release(type_handler);
4125 IMFStreamDescriptor_Release(stream_desc);
4127 /* IsMediaTypeSupported() for unset current type. */
4128 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4129 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4131 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4132 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4134 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4135 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4137 /* Initialize one from initial type set. */
4138 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4139 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4141 media_type2 = (void *)0xdeadbeef;
4142 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4143 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4144 ok(!media_type2, "Unexpected pointer.\n");
4146 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4147 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4149 media_type2 = (void *)0xdeadbeef;
4150 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4151 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4152 ok(!media_type2, "Unexpected pointer.\n");
4154 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4155 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4157 media_type2 = (void *)0xdeadbeef;
4158 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4160 ok(!media_type2, "Unexpected pointer.\n");
4162 /* Now set current type that's not compatible. */
4163 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4164 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4166 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4167 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4169 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4170 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4172 media_type2 = (void *)0xdeadbeef;
4173 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4174 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4175 ok(!media_type2, "Unexpected pointer.\n");
4177 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4178 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4180 media_type2 = (void *)0xdeadbeef;
4181 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4182 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4183 ok(!media_type2, "Unexpected pointer.\n");
4185 IMFMediaType_Release(media_type);
4186 IMFMediaType_Release(media_type3);
4188 IMFMediaTypeHandler_Release(type_handler);
4190 IMFStreamDescriptor_Release(stream_desc);
4192 /* Major type is returned for first entry. */
4193 hr = MFCreateMediaType(&media_types[0]);
4194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4195 hr = MFCreateMediaType(&media_types[1]);
4196 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4198 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4199 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4200 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4201 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4203 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4204 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4206 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4207 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4209 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4211 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4213 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4214 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4215 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4216 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4218 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4219 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4220 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4222 IMFMediaType_Release(media_types[0]);
4223 IMFMediaType_Release(media_types[1]);
4225 IMFMediaTypeHandler_Release(type_handler);
4226 IMFStreamDescriptor_Release(stream_desc);
4229 static const struct image_size_test
4231 const GUID *subtype;
4232 UINT32 width;
4233 UINT32 height;
4234 UINT32 size;
4235 UINT32 plane_size; /* Matches image size when 0. */
4237 image_size_tests[] =
4239 { &MFVideoFormat_RGB8, 3, 5, 20 },
4240 { &MFVideoFormat_RGB8, 1, 1, 4 },
4241 { &MFVideoFormat_RGB555, 3, 5, 40 },
4242 { &MFVideoFormat_RGB555, 1, 1, 4 },
4243 { &MFVideoFormat_RGB565, 3, 5, 40 },
4244 { &MFVideoFormat_RGB565, 1, 1, 4 },
4245 { &MFVideoFormat_RGB24, 3, 5, 60 },
4246 { &MFVideoFormat_RGB24, 1, 1, 4 },
4247 { &MFVideoFormat_RGB32, 3, 5, 60 },
4248 { &MFVideoFormat_RGB32, 1, 1, 4 },
4249 { &MFVideoFormat_ARGB32, 3, 5, 60 },
4250 { &MFVideoFormat_ARGB32, 1, 1, 4 },
4251 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
4252 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
4253 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
4254 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
4256 /* YUV */
4257 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
4258 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
4259 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
4260 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
4261 { &MFVideoFormat_NV12, 4, 2, 12 },
4262 { &MFVideoFormat_NV12, 320, 240, 115200 },
4263 { &MFVideoFormat_AYUV, 1, 1, 4 },
4264 { &MFVideoFormat_AYUV, 2, 1, 8 },
4265 { &MFVideoFormat_AYUV, 1, 2, 8 },
4266 { &MFVideoFormat_AYUV, 4, 3, 48 },
4267 { &MFVideoFormat_AYUV, 320, 240, 307200 },
4268 { &MFVideoFormat_IMC1, 1, 1, 4 },
4269 { &MFVideoFormat_IMC1, 2, 1, 4 },
4270 { &MFVideoFormat_IMC1, 1, 2, 8 },
4271 { &MFVideoFormat_IMC1, 4, 3, 24 },
4272 { &MFVideoFormat_IMC1, 320, 240, 153600 },
4273 { &MFVideoFormat_IMC3, 1, 1, 4 },
4274 { &MFVideoFormat_IMC3, 2, 1, 4 },
4275 { &MFVideoFormat_IMC3, 1, 2, 8 },
4276 { &MFVideoFormat_IMC3, 4, 3, 24 },
4277 { &MFVideoFormat_IMC3, 320, 240, 153600 },
4278 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
4279 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
4280 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
4281 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
4282 { &MFVideoFormat_IMC2, 4, 2, 12 },
4283 { &MFVideoFormat_IMC2, 320, 240, 115200 },
4284 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
4285 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
4286 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
4287 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
4288 { &MFVideoFormat_IMC4, 4, 2, 12 },
4289 { &MFVideoFormat_IMC4, 320, 240, 115200 },
4290 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
4291 { &MFVideoFormat_YV12, 2, 1, 3 },
4292 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
4293 { &MFVideoFormat_YV12, 4, 3, 18 },
4294 { &MFVideoFormat_YV12, 320, 240, 115200 },
4296 { &MFVideoFormat_I420, 1, 1, 3, 1 },
4297 { &MFVideoFormat_I420, 2, 1, 3 },
4298 { &MFVideoFormat_I420, 1, 2, 6, 3 },
4299 { &MFVideoFormat_I420, 4, 3, 18 },
4300 { &MFVideoFormat_I420, 320, 240, 115200 },
4302 { &MFVideoFormat_IYUV, 1, 1, 3, 1 },
4303 { &MFVideoFormat_IYUV, 2, 1, 3 },
4304 { &MFVideoFormat_IYUV, 1, 2, 6, 3 },
4305 { &MFVideoFormat_IYUV, 4, 3, 18 },
4306 { &MFVideoFormat_IYUV, 320, 240, 115200 },
4308 { &MFVideoFormat_YUY2, 2, 1, 4 },
4309 { &MFVideoFormat_YUY2, 4, 3, 24 },
4310 { &MFVideoFormat_YUY2, 128, 128, 32768 },
4311 { &MFVideoFormat_YUY2, 320, 240, 153600 },
4313 { &MFVideoFormat_UYVY, 2, 1, 4 },
4314 { &MFVideoFormat_UYVY, 4, 3, 24 },
4315 { &MFVideoFormat_UYVY, 128, 128, 32768 },
4316 { &MFVideoFormat_UYVY, 320, 240, 153600 },
4319 static void test_MFCalculateImageSize(void)
4321 unsigned int i;
4322 UINT32 size;
4323 HRESULT hr;
4325 size = 1;
4326 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4327 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4328 ok(size == 0, "Unexpected size %u.\n", size);
4330 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4332 const struct image_size_test *ptr = &image_size_tests[i];
4334 /* Those are supported since Win10. */
4335 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4336 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4338 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4339 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4340 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4341 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4345 static void test_MFGetPlaneSize(void)
4347 unsigned int i;
4348 DWORD size;
4349 HRESULT hr;
4351 if (!pMFGetPlaneSize)
4353 win_skip("MFGetPlaneSize() is not available.\n");
4354 return;
4357 size = 1;
4358 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4360 ok(size == 0, "Unexpected size %lu.\n", size);
4362 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4364 const struct image_size_test *ptr = &image_size_tests[i];
4365 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4367 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4368 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4369 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u.\n", i, size, plane_size);
4373 static void test_MFCompareFullToPartialMediaType(void)
4375 IMFMediaType *full_type, *partial_type;
4376 HRESULT hr;
4377 BOOL ret;
4379 hr = MFCreateMediaType(&full_type);
4380 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4382 hr = MFCreateMediaType(&partial_type);
4383 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4385 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4386 ok(!ret, "Unexpected result %d.\n", ret);
4388 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4389 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4391 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4392 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4394 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4395 ok(ret, "Unexpected result %d.\n", ret);
4397 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4398 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4400 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4401 ok(ret, "Unexpected result %d.\n", ret);
4403 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4404 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4406 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4407 ok(!ret, "Unexpected result %d.\n", ret);
4409 IMFMediaType_Release(full_type);
4410 IMFMediaType_Release(partial_type);
4413 static void test_attributes_serialization(void)
4415 static const UINT8 blob[] = {1,2,3};
4416 IMFAttributes *attributes, *dest;
4417 UINT32 size, count, value32;
4418 double value_dbl;
4419 UINT64 value64;
4420 UINT8 *buffer;
4421 IUnknown *obj;
4422 HRESULT hr;
4423 WCHAR *str;
4424 GUID guid;
4426 hr = MFCreateAttributes(&attributes, 0);
4427 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4429 hr = MFCreateAttributes(&dest, 0);
4430 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4432 hr = MFGetAttributesAsBlobSize(attributes, &size);
4433 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4434 ok(size == 8, "Got size %u.\n", size);
4436 buffer = malloc(size);
4438 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4439 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4441 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4442 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4444 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4445 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4447 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4448 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4450 hr = MFInitAttributesFromBlob(dest, buffer, size);
4451 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4453 /* Previous items are cleared. */
4454 hr = IMFAttributes_GetCount(dest, &count);
4455 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4456 ok(count == 0, "Unexpected count %u.\n", count);
4458 free(buffer);
4460 /* Set some attributes of various types. */
4461 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4462 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4463 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4464 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4465 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4466 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4467 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4469 hr = MFGetAttributesAsBlobSize(attributes, &size);
4470 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4471 ok(size > 8, "Got unexpected size %u.\n", size);
4473 buffer = malloc(size);
4474 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4475 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4476 hr = MFInitAttributesFromBlob(dest, buffer, size);
4477 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4478 free(buffer);
4480 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4481 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
4482 ok(value32 == 456, "Unexpected value %u.\n", value32);
4483 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4484 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
4485 ok(value64 == 123, "Unexpected value.\n");
4486 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4487 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
4488 ok(value_dbl == 0.5, "Unexpected value.\n");
4489 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4490 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4491 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4492 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
4493 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4494 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4495 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
4496 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4497 CoTaskMemFree(str);
4498 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4499 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
4500 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4501 CoTaskMemFree(buffer);
4503 IMFAttributes_Release(attributes);
4504 IMFAttributes_Release(dest);
4507 static void test_wrapped_media_type(void)
4509 IMFMediaType *mediatype, *mediatype2;
4510 UINT32 count, type;
4511 HRESULT hr;
4512 GUID guid;
4514 hr = MFCreateMediaType(&mediatype);
4515 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4517 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4518 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4520 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4521 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4522 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4523 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4525 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4526 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
4528 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4529 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
4531 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4532 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4533 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4535 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4536 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
4537 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4539 hr = IMFMediaType_GetCount(mediatype2, &count);
4540 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
4541 ok(count == 3, "Unexpected count %u.\n", count);
4543 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4544 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
4545 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4547 IMFMediaType_Release(mediatype);
4549 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4550 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
4552 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4553 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4554 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4556 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4557 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4559 IMFMediaType_Release(mediatype);
4560 IMFMediaType_Release(mediatype2);
4563 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4565 static const struct wave_fmt_test
4567 const GUID *subtype;
4568 WORD format_tag;
4570 wave_fmt_tests[] =
4572 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
4573 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
4575 WAVEFORMATEXTENSIBLE *format_ext;
4576 IMFMediaType *mediatype;
4577 WAVEFORMATEX *format;
4578 UINT32 size, i;
4579 HRESULT hr;
4581 hr = MFCreateMediaType(&mediatype);
4582 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4584 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4585 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4587 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4588 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4590 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4591 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4593 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4594 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4596 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4597 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4599 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
4601 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
4602 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4604 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4605 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4606 ok(format != NULL, "Expected format structure.\n");
4607 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4608 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
4609 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4610 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
4611 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
4612 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4613 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4614 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4615 CoTaskMemFree(format);
4617 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4618 MFWaveFormatExConvertFlag_ForceExtensible);
4619 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4620 ok(format_ext != NULL, "Expected format structure.\n");
4621 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4622 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4623 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4624 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
4625 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
4626 format_ext->Format.nAvgBytesPerSec);
4627 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4628 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4629 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4630 format_ext->Format.cbSize);
4631 CoTaskMemFree(format_ext);
4633 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4634 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4635 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4636 CoTaskMemFree(format);
4639 IMFMediaType_Release(mediatype);
4642 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4644 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4645 IMFByteStream *stream;
4646 IUnknown *object;
4647 HRESULT hr;
4649 ok(!!result, "Unexpected result object.\n");
4651 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4653 hr = IMFAsyncResult_GetObject(result, &object);
4654 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4656 hr = MFEndCreateFile(result, &stream);
4657 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
4658 IMFByteStream_Release(stream);
4660 SetEvent(callback->event);
4662 return S_OK;
4665 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4667 testcallback_QueryInterface,
4668 testcallback_AddRef,
4669 testcallback_Release,
4670 testcallback_GetParameters,
4671 test_create_file_callback_Invoke,
4674 static void test_async_create_file(void)
4676 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4677 struct test_callback *callback;
4678 IUnknown *cancel_cookie;
4679 HRESULT hr;
4680 BOOL ret;
4682 callback = create_test_callback(&test_create_file_callback_vtbl);
4684 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4685 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
4687 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
4689 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4690 GetTempFileNameW(pathW, NULL, 0, fileW);
4692 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4693 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
4694 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
4695 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4697 WaitForSingleObject(callback->event, INFINITE);
4699 IUnknown_Release(cancel_cookie);
4701 CloseHandle(callback->event);
4703 hr = MFShutdown();
4704 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4706 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4708 ret = DeleteFileW(fileW);
4709 ok(ret, "Failed to delete test file.\n");
4712 struct activate_object
4714 IMFActivate IMFActivate_iface;
4715 LONG refcount;
4718 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4720 if (IsEqualIID(riid, &IID_IMFActivate) ||
4721 IsEqualIID(riid, &IID_IMFAttributes) ||
4722 IsEqualIID(riid, &IID_IUnknown))
4724 *obj = iface;
4725 IMFActivate_AddRef(iface);
4726 return S_OK;
4729 *obj = NULL;
4730 return E_NOINTERFACE;
4733 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4735 return 2;
4738 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4740 return 1;
4743 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4745 return E_NOTIMPL;
4748 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4750 return E_NOTIMPL;
4753 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4755 return E_NOTIMPL;
4758 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4759 BOOL *result)
4761 return E_NOTIMPL;
4764 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4766 return E_NOTIMPL;
4769 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4771 return E_NOTIMPL;
4774 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4776 return E_NOTIMPL;
4779 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4781 return E_NOTIMPL;
4784 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4786 return E_NOTIMPL;
4789 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4790 UINT32 size, UINT32 *length)
4792 return E_NOTIMPL;
4795 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4796 WCHAR **value, UINT32 *length)
4798 return E_NOTIMPL;
4801 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4803 return E_NOTIMPL;
4806 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4807 UINT32 bufsize, UINT32 *blobsize)
4809 return E_NOTIMPL;
4812 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4814 return E_NOTIMPL;
4817 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4819 return E_NOTIMPL;
4822 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4824 return E_NOTIMPL;
4827 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4829 return E_NOTIMPL;
4832 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4834 return E_NOTIMPL;
4837 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4839 return E_NOTIMPL;
4842 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4844 return E_NOTIMPL;
4847 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4849 return E_NOTIMPL;
4852 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4854 return E_NOTIMPL;
4857 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4859 return E_NOTIMPL;
4862 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4864 return E_NOTIMPL;
4867 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4869 return E_NOTIMPL;
4872 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4874 return E_NOTIMPL;
4877 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4879 return E_NOTIMPL;
4882 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4884 return E_NOTIMPL;
4887 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4889 return E_NOTIMPL;
4892 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4894 return E_NOTIMPL;
4897 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4899 return E_NOTIMPL;
4902 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4904 return E_NOTIMPL;
4907 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4909 return E_NOTIMPL;
4912 static const IMFActivateVtbl activate_object_vtbl =
4914 activate_object_QueryInterface,
4915 activate_object_AddRef,
4916 activate_object_Release,
4917 activate_object_GetItem,
4918 activate_object_GetItemType,
4919 activate_object_CompareItem,
4920 activate_object_Compare,
4921 activate_object_GetUINT32,
4922 activate_object_GetUINT64,
4923 activate_object_GetDouble,
4924 activate_object_GetGUID,
4925 activate_object_GetStringLength,
4926 activate_object_GetString,
4927 activate_object_GetAllocatedString,
4928 activate_object_GetBlobSize,
4929 activate_object_GetBlob,
4930 activate_object_GetAllocatedBlob,
4931 activate_object_GetUnknown,
4932 activate_object_SetItem,
4933 activate_object_DeleteItem,
4934 activate_object_DeleteAllItems,
4935 activate_object_SetUINT32,
4936 activate_object_SetUINT64,
4937 activate_object_SetDouble,
4938 activate_object_SetGUID,
4939 activate_object_SetString,
4940 activate_object_SetBlob,
4941 activate_object_SetUnknown,
4942 activate_object_LockStore,
4943 activate_object_UnlockStore,
4944 activate_object_GetCount,
4945 activate_object_GetItemByIndex,
4946 activate_object_CopyAllItems,
4947 activate_object_ActivateObject,
4948 activate_object_ShutdownObject,
4949 activate_object_DetachObject,
4952 static void test_local_handlers(void)
4954 IMFActivate local_activate = { &activate_object_vtbl };
4955 static const WCHAR localW[] = L"local";
4956 HRESULT hr;
4958 if (!pMFRegisterLocalSchemeHandler)
4960 win_skip("Local handlers are not supported.\n");
4961 return;
4964 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4965 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4967 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4968 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4970 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4971 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4973 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4974 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
4976 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4977 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
4979 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4980 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4982 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4983 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4985 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4986 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4988 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4989 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4991 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4992 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4995 static void test_create_property_store(void)
4997 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4998 IPropertyStore *store, *store2;
4999 PROPVARIANT value = {0};
5000 PROPERTYKEY key;
5001 ULONG refcount;
5002 DWORD count;
5003 HRESULT hr;
5005 hr = CreatePropertyStore(NULL);
5006 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5008 hr = CreatePropertyStore(&store);
5009 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5011 hr = CreatePropertyStore(&store2);
5012 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
5013 ok(store2 != store, "Expected different store objects.\n");
5014 IPropertyStore_Release(store2);
5016 check_interface(store, &IID_IPropertyStoreCache, FALSE);
5017 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
5019 hr = IPropertyStore_GetCount(store, NULL);
5020 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5022 count = 0xdeadbeef;
5023 hr = IPropertyStore_GetCount(store, &count);
5024 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5025 ok(!count, "Unexpected count %lu.\n", count);
5027 hr = IPropertyStore_Commit(store);
5028 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5030 hr = IPropertyStore_GetAt(store, 0, &key);
5031 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5033 hr = IPropertyStore_GetValue(store, NULL, &value);
5034 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5036 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5037 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5039 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5040 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5042 memset(&value, 0, sizeof(PROPVARIANT));
5043 value.vt = VT_I4;
5044 value.lVal = 0xdeadbeef;
5045 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5046 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5048 if (0)
5050 /* crashes on Windows */
5051 hr = IPropertyStore_SetValue(store, NULL, &value);
5052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5055 hr = IPropertyStore_GetCount(store, &count);
5056 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5057 ok(count == 1, "Unexpected count %lu.\n", count);
5059 hr = IPropertyStore_Commit(store);
5060 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5062 hr = IPropertyStore_GetAt(store, 0, &key);
5063 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5064 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5066 hr = IPropertyStore_GetAt(store, 1, &key);
5067 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5069 memset(&value, 0xcc, sizeof(PROPVARIANT));
5070 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5071 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5072 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5073 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5075 memset(&value, 0, sizeof(PROPVARIANT));
5076 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5077 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5079 hr = IPropertyStore_GetCount(store, &count);
5080 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5081 ok(count == 1, "Unexpected count %lu.\n", count);
5083 memset(&value, 0xcc, sizeof(PROPVARIANT));
5084 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5085 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5086 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5087 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5089 refcount = IPropertyStore_Release(store);
5090 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5093 struct test_thread_param
5095 IMFDXGIDeviceManager *manager;
5096 HANDLE handle;
5097 BOOL lock;
5100 static DWORD WINAPI test_device_manager_thread(void *arg)
5102 struct test_thread_param *param = arg;
5103 ID3D11Device *device;
5104 HRESULT hr;
5106 if (param->lock)
5108 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5109 (void **)&device, FALSE);
5110 if (SUCCEEDED(hr))
5111 ID3D11Device_Release(device);
5113 else
5114 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5116 return hr;
5119 static void test_dxgi_device_manager(void)
5121 IMFDXGIDeviceManager *manager, *manager2;
5122 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5123 struct test_thread_param param;
5124 HANDLE handle1, handle, thread;
5125 UINT token, token2;
5126 IUnknown *unk;
5127 HRESULT hr;
5129 if (!pMFCreateDXGIDeviceManager)
5131 win_skip("MFCreateDXGIDeviceManager not found.\n");
5132 return;
5135 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5136 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5138 token = 0;
5139 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5140 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5141 ok(!token, "got wrong token: %u.\n", token);
5143 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5144 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5145 EXPECT_REF(manager, 1);
5146 ok(!!token, "got wrong token: %u.\n", token);
5148 Sleep(50);
5149 token2 = 0;
5150 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5151 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5152 EXPECT_REF(manager2, 1);
5153 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5154 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5155 EXPECT_REF(manager, 1);
5157 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5158 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5160 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5161 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5163 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5164 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5166 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5167 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5168 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5169 EXPECT_REF(d3d11_dev, 1);
5171 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5172 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5173 EXPECT_REF(d3d11_dev, 1);
5175 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5176 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5178 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5179 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5180 EXPECT_REF(manager, 1);
5181 EXPECT_REF(d3d11_dev, 2);
5183 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5184 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5185 EXPECT_REF(manager2, 1);
5186 EXPECT_REF(d3d11_dev, 2);
5188 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5189 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5190 EXPECT_REF(manager, 1);
5191 EXPECT_REF(d3d11_dev, 2);
5193 /* GetVideoService() on device change. */
5194 handle = NULL;
5195 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5196 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5197 ok(!!handle, "Unexpected handle value %p.\n", handle);
5199 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5200 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5201 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5202 EXPECT_REF(d3d11_dev2, 1);
5203 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5204 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5205 EXPECT_REF(manager, 1);
5206 EXPECT_REF(d3d11_dev2, 2);
5207 EXPECT_REF(d3d11_dev, 1);
5209 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5210 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5212 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5213 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5215 handle = NULL;
5216 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5217 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5218 ok(!!handle, "Unexpected handle value %p.\n", handle);
5220 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5221 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5223 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5224 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5225 IUnknown_Release(unk);
5227 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5228 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5229 IUnknown_Release(unk);
5231 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5233 IUnknown_Release(unk);
5235 handle1 = NULL;
5236 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5238 ok(handle != handle1, "Unexpected handle.\n");
5240 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5241 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5243 /* Already closed. */
5244 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5245 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5247 handle = NULL;
5248 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5251 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5254 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5255 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5257 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5258 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5259 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5260 ID3D11Device_Release(device);
5262 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5265 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5266 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5268 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5269 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5271 /* Locked with one handle, unlock with another. */
5272 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5273 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5275 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5276 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5278 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5279 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5281 ID3D11Device_Release(device);
5283 /* Closing unlocks the device. */
5284 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5287 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5288 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5289 ID3D11Device_Release(device);
5291 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5292 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5294 /* Open two handles. */
5295 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5296 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5298 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5299 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5301 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5303 ID3D11Device_Release(device);
5305 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5306 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5307 ID3D11Device_Release(device);
5309 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5310 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5312 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5313 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5315 param.manager = manager;
5316 param.handle = handle;
5317 param.lock = TRUE;
5318 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5319 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5320 GetExitCodeThread(thread, (DWORD *)&hr);
5321 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5322 CloseHandle(thread);
5324 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5325 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5327 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5328 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5330 /* Lock on main thread, unlock on another. */
5331 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5333 ID3D11Device_Release(device);
5335 param.manager = manager;
5336 param.handle = handle;
5337 param.lock = FALSE;
5338 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5339 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5340 GetExitCodeThread(thread, (DWORD *)&hr);
5341 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5342 CloseHandle(thread);
5344 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5345 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5347 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5348 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5350 IMFDXGIDeviceManager_Release(manager);
5351 EXPECT_REF(d3d11_dev2, 1);
5352 ID3D11Device_Release(d3d11_dev);
5353 ID3D11Device_Release(d3d11_dev2);
5354 IMFDXGIDeviceManager_Release(manager2);
5357 static void test_MFCreateTransformActivate(void)
5359 IMFActivate *activate;
5360 UINT32 count;
5361 HRESULT hr;
5363 if (!pMFCreateTransformActivate)
5365 win_skip("MFCreateTransformActivate() is not available.\n");
5366 return;
5369 hr = pMFCreateTransformActivate(&activate);
5370 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5372 hr = IMFActivate_GetCount(activate, &count);
5373 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5374 ok(!count, "Unexpected attribute count %u.\n", count);
5376 IMFActivate_Release(activate);
5379 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5381 if (IsEqualIID(riid, &IID_IClassFactory) ||
5382 IsEqualIID(riid, &IID_IUnknown))
5384 *obj = iface;
5385 IClassFactory_AddRef(iface);
5386 return S_OK;
5389 *obj = NULL;
5390 return E_NOINTERFACE;
5393 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5395 return 2;
5398 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5400 return 1;
5403 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5405 ok(0, "Unexpected call.\n");
5406 return E_NOTIMPL;
5409 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5411 return S_OK;
5414 static const IClassFactoryVtbl test_mft_factory_vtbl =
5416 test_mft_factory_QueryInterface,
5417 test_mft_factory_AddRef,
5418 test_mft_factory_Release,
5419 test_mft_factory_CreateInstance,
5420 test_mft_factory_LockServer,
5423 static void test_MFTRegisterLocal(void)
5425 IClassFactory test_factory = { &test_mft_factory_vtbl };
5426 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5427 IMFAttributes *attributes;
5428 IMFActivate **activate;
5429 UINT32 count, count2;
5430 WCHAR *name;
5431 HRESULT hr;
5433 if (!pMFTRegisterLocal)
5435 win_skip("MFTRegisterLocal() is not available.\n");
5436 return;
5439 input_types[0].guidMajorType = MFMediaType_Audio;
5440 input_types[0].guidSubtype = MFAudioFormat_PCM;
5441 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5442 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5444 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5445 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5447 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5448 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5449 ok(count > 0, "Unexpected count %u.\n", count);
5450 CoTaskMemFree(activate);
5452 hr = pMFTUnregisterLocal(&test_factory);
5453 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5455 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5457 ok(count2 < count, "Unexpected count %u.\n", count2);
5458 CoTaskMemFree(activate);
5460 hr = pMFTUnregisterLocal(&test_factory);
5461 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5463 hr = pMFTUnregisterLocal(NULL);
5464 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5466 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5467 0, NULL);
5468 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5470 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5471 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5473 hr = pMFTUnregisterLocal(NULL);
5474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5476 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5477 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5479 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5480 0, NULL);
5481 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5483 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5484 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5487 static void test_queue_com(void)
5489 static int system_queues[] =
5491 MFASYNC_CALLBACK_QUEUE_STANDARD,
5492 MFASYNC_CALLBACK_QUEUE_RT,
5493 MFASYNC_CALLBACK_QUEUE_IO,
5494 MFASYNC_CALLBACK_QUEUE_TIMER,
5495 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5496 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5499 static int user_queues[] =
5501 MF_STANDARD_WORKQUEUE,
5502 MF_WINDOW_WORKQUEUE,
5503 MF_MULTITHREADED_WORKQUEUE,
5506 char path_name[MAX_PATH];
5507 PROCESS_INFORMATION info;
5508 STARTUPINFOA startup;
5509 char **argv;
5510 int i;
5512 if (!pCoGetApartmentType)
5514 win_skip("CoGetApartmentType() is not available.\n");
5515 return;
5518 winetest_get_mainargs(&argv);
5520 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5522 memset(&startup, 0, sizeof(startup));
5523 startup.cb = sizeof(startup);
5524 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5525 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5526 "CreateProcess failed.\n" );
5527 wait_child_process(info.hProcess);
5528 CloseHandle(info.hProcess);
5529 CloseHandle(info.hThread);
5532 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5534 memset(&startup, 0, sizeof(startup));
5535 startup.cb = sizeof(startup);
5536 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5537 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5538 "CreateProcess failed.\n" );
5539 wait_child_process(info.hProcess);
5540 CloseHandle(info.hProcess);
5541 CloseHandle(info.hThread);
5545 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5547 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5548 APTTYPEQUALIFIER qualifier;
5549 APTTYPE com_type;
5550 HRESULT hr;
5552 hr = pCoGetApartmentType(&com_type, &qualifier);
5553 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
5554 if (SUCCEEDED(hr))
5556 todo_wine {
5557 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5558 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5559 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5560 else
5561 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5562 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5566 SetEvent(callback->event);
5567 return S_OK;
5570 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5572 testcallback_QueryInterface,
5573 testcallback_AddRef,
5574 testcallback_Release,
5575 testcallback_GetParameters,
5576 test_queue_com_state_callback_Invoke,
5579 static void test_queue_com_state(const char *name)
5581 struct test_callback *callback;
5582 DWORD queue, queue_type;
5583 HRESULT hr;
5585 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
5586 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
5588 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5589 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
5591 if (name[0] == 's')
5593 callback->param = name[1] - '0';
5594 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
5595 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5596 WaitForSingleObject(callback->event, INFINITE);
5598 else if (name[0] == 'u')
5600 queue_type = name[1] - '0';
5602 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5603 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5604 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
5606 if (SUCCEEDED(hr))
5608 callback->param = queue;
5609 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
5610 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5611 WaitForSingleObject(callback->event, INFINITE);
5613 hr = MFUnlockWorkQueue(queue);
5614 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
5618 CloseHandle(callback->event);
5620 hr = MFShutdown();
5621 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5623 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5626 static void test_MFGetStrideForBitmapInfoHeader(void)
5628 static const struct stride_test
5630 const GUID *subtype;
5631 unsigned int width;
5632 LONG stride;
5634 stride_tests[] =
5636 { &MFVideoFormat_RGB8, 3, -4 },
5637 { &MFVideoFormat_RGB8, 1, -4 },
5638 { &MFVideoFormat_RGB555, 3, -8 },
5639 { &MFVideoFormat_RGB555, 1, -4 },
5640 { &MFVideoFormat_RGB565, 3, -8 },
5641 { &MFVideoFormat_RGB565, 1, -4 },
5642 { &MFVideoFormat_RGB24, 3, -12 },
5643 { &MFVideoFormat_RGB24, 1, -4 },
5644 { &MFVideoFormat_RGB32, 3, -12 },
5645 { &MFVideoFormat_RGB32, 1, -4 },
5646 { &MFVideoFormat_ARGB32, 3, -12 },
5647 { &MFVideoFormat_ARGB32, 1, -4 },
5648 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5649 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5650 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5651 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5653 /* YUV */
5654 { &MFVideoFormat_NV12, 1, 1 },
5655 { &MFVideoFormat_NV12, 2, 2 },
5656 { &MFVideoFormat_NV12, 3, 3 },
5657 { &MFVideoFormat_AYUV, 1, 4 },
5658 { &MFVideoFormat_AYUV, 4, 16 },
5659 { &MFVideoFormat_AYUV, 5, 20 },
5660 { &MFVideoFormat_IMC1, 1, 4 },
5661 { &MFVideoFormat_IMC1, 2, 4 },
5662 { &MFVideoFormat_IMC1, 3, 8 },
5663 { &MFVideoFormat_IMC3, 1, 4 },
5664 { &MFVideoFormat_IMC3, 2, 4 },
5665 { &MFVideoFormat_IMC3, 3, 8 },
5666 { &MFVideoFormat_IMC2, 1, 1 },
5667 { &MFVideoFormat_IMC2, 2, 2 },
5668 { &MFVideoFormat_IMC2, 3, 3 },
5669 { &MFVideoFormat_IMC4, 1, 1 },
5670 { &MFVideoFormat_IMC4, 2, 2 },
5671 { &MFVideoFormat_IMC4, 3, 3 },
5672 { &MFVideoFormat_YV12, 1, 1 },
5673 { &MFVideoFormat_YV12, 2, 2 },
5674 { &MFVideoFormat_YV12, 3, 3 },
5675 { &MFVideoFormat_YV12, 320, 320 },
5676 { &MFVideoFormat_I420, 1, 1 },
5677 { &MFVideoFormat_I420, 2, 2 },
5678 { &MFVideoFormat_I420, 3, 3 },
5679 { &MFVideoFormat_I420, 320, 320 },
5680 { &MFVideoFormat_IYUV, 1, 1 },
5681 { &MFVideoFormat_IYUV, 2, 2 },
5682 { &MFVideoFormat_IYUV, 3, 3 },
5683 { &MFVideoFormat_IYUV, 320, 320 },
5685 unsigned int i;
5686 LONG stride;
5687 HRESULT hr;
5689 if (!pMFGetStrideForBitmapInfoHeader)
5691 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5692 return;
5695 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5696 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5698 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5700 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5701 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
5702 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
5703 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5707 static void test_MFCreate2DMediaBuffer(void)
5709 static const struct _2d_buffer_test
5711 unsigned int width;
5712 unsigned int height;
5713 unsigned int fourcc;
5714 unsigned int contiguous_length;
5715 int pitch;
5716 unsigned int max_length;
5717 } _2d_buffer_tests[] =
5719 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64, 192 },
5720 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5721 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5722 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5723 { 4, 16, MAKEFOURCC('N','V','1','2'), 96, 64, 1536 },
5725 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128, 384 },
5726 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5727 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5728 { 3, 5, MAKEFOURCC('I','M','C','2'), 20, 128 },
5729 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5730 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5731 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5732 { 3, 5, MAKEFOURCC('I','M','C','4'), 20, 128 },
5734 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128 },
5735 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128 },
5736 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 4096 },
5737 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128 },
5739 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128 },
5740 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128 },
5741 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 4096 },
5742 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128 },
5744 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5745 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5746 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128, 3072 },
5748 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5749 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5750 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64, 1024 },
5752 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5753 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5754 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64, 1024 },
5756 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5757 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5758 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64, 1024 },
5760 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5761 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5762 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5764 static const char two_aas[] = { 0xaa, 0xaa };
5765 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
5766 DWORD max_length, length, length2;
5767 BYTE *buffer_start, *data, *data2;
5768 LONG pitch, pitch2, stride;
5769 IMF2DBuffer2 *_2dbuffer2;
5770 IMF2DBuffer *_2dbuffer;
5771 IMFMediaBuffer *buffer;
5772 int i, j, k;
5773 HRESULT hr;
5774 BOOL ret;
5776 if (!pMFCreate2DMediaBuffer)
5778 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5779 return;
5782 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5783 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5785 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5786 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5788 /* YUV formats can't be bottom-up. */
5789 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5790 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5792 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5793 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5795 check_interface(buffer, &IID_IMFGetService, TRUE);
5796 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5798 /* Full backing buffer size, with 64 bytes per row alignment. */
5799 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5800 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5801 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
5803 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5804 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5805 ok(!length, "Unexpected length.\n");
5807 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5808 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
5810 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5811 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5812 ok(length == 10, "Unexpected length.\n");
5814 /* Linear lock/unlock. */
5816 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5817 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5819 /* Linear locking call returns plane size.*/
5820 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5821 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5822 ok(max_length == length, "Unexpected length.\n");
5824 memset(data, 0xaa, length);
5826 length = 0;
5827 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5828 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
5830 /* Already locked */
5831 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5832 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5833 ok(data2 == data, "Unexpected pointer.\n");
5835 hr = IMFMediaBuffer_Unlock(buffer);
5836 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5838 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5839 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
5841 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5842 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5844 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5845 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5846 ok(length == 9, "Unexpected length %lu.\n", length);
5848 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5849 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5851 /* 2D lock. */
5852 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5853 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
5855 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5856 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5858 hr = IMFMediaBuffer_Unlock(buffer);
5859 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5861 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5862 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5864 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5865 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5867 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5868 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5870 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5871 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5873 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5874 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5875 ok(!!data, "Expected data pointer.\n");
5876 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
5878 for (i = 0; i < 4; i++)
5879 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
5880 memset(data, 0xbb, 194);
5882 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5883 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5884 ok(data == data2, "Expected data pointer.\n");
5886 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5887 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5889 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5890 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5892 /* Active 2D lock */
5893 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5894 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5896 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5897 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5899 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5900 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5902 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5903 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5905 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5906 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5908 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5909 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5911 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
5913 hr = IMFMediaBuffer_Unlock(buffer);
5914 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5916 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5917 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
5919 if (SUCCEEDED(hr))
5921 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5922 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5924 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5925 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5927 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5928 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5930 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5931 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5933 /* Flags are ignored. */
5934 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5935 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5937 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5938 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5940 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5941 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5943 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5944 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5946 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5947 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5949 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5950 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5952 IMF2DBuffer2_Release(_2dbuffer2);
5954 else
5955 win_skip("IMF2DBuffer2 is not supported.\n");
5957 IMF2DBuffer_Release(_2dbuffer);
5959 IMFMediaBuffer_Release(buffer);
5961 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5963 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5965 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5966 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5968 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5969 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5970 if (ptr->max_length)
5971 ok(length == ptr->max_length, "%u: unexpected maximum length %lu for %u x %u, format %s.\n",
5972 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5974 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5975 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
5977 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5978 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5979 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %lu for %u x %u, format %s.\n",
5980 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5982 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5983 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5984 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
5985 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5987 hr = pMFGetStrideForBitmapInfoHeader(ptr->fourcc, ptr->width, &stride);
5988 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
5989 stride = abs(stride);
5991 /* primary plane */
5992 ok(ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
5993 ptr->height * stride, length2);
5994 for (j = 0; j < ptr->height; j++)
5995 for (k = 0; k < stride; k++)
5996 data[j * stride + k] = ((j % 16) << 4) + (k % 16);
5998 data += ptr->height * stride;
6000 /* secondary planes */
6001 switch (ptr->fourcc)
6003 case MAKEFOURCC('I','M','C','1'):
6004 case MAKEFOURCC('I','M','C','3'):
6005 ok(2 * ptr->height * stride <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6006 2 * ptr->height * stride, length2);
6007 for (j = 0; j < ptr->height; j++)
6008 for (k = 0; k < stride / 2; k++)
6009 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6010 break;
6012 case MAKEFOURCC('I','M','C','2'):
6013 case MAKEFOURCC('I','M','C','4'):
6014 ok(stride * 3 / 2 * ptr->height <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6015 stride * 3 / 2 * ptr->height, length2);
6016 for (j = 0; j < ptr->height; j++)
6017 for (k = 0; k < stride / 2; k++)
6018 data[j * (stride / 2) + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6019 break;
6021 case MAKEFOURCC('N','V','1','2'):
6022 ok(stride * ptr->height * 3 / 2 <= length2, "Insufficient buffer space: expected at least %lu bytes, got only %lu\n",
6023 stride * ptr->height * 3 / 2, length2);
6024 for (j = 0; j < ptr->height / 2; j++)
6025 for (k = 0; k < stride; k++)
6026 data[j * stride + k] = (((j + ptr->height) % 16) << 4) + (k % 16);
6027 break;
6030 hr = IMFMediaBuffer_Unlock(buffer);
6031 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6033 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6034 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6036 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
6037 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
6038 ok(data2 == data, "Unexpected data pointer.\n");
6039 ok(pitch == pitch2, "Unexpected pitch.\n");
6041 /* primary plane */
6042 for (j = 0; j < ptr->height; j++)
6043 for (k = 0; k < stride; k++)
6044 ok(data[j * pitch + k] == ((j % 16) << 4) + (k % 16),
6045 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6046 data[j * pitch + k], ((j % 16) << 4) + (k % 16), i, j, k);
6048 data += ptr->height * pitch;
6050 /* secondary planes */
6051 switch (ptr->fourcc)
6053 case MAKEFOURCC('I','M','C','1'):
6054 case MAKEFOURCC('I','M','C','3'):
6055 for (j = 0; j < ptr->height; j++)
6056 for (k = 0; k < stride / 2; k++)
6057 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6058 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6059 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6060 break;
6062 case MAKEFOURCC('I','M','C','2'):
6063 case MAKEFOURCC('I','M','C','4'):
6064 for (j = 0; j < ptr->height; j++)
6065 for (k = 0; k < stride / 2; k++)
6066 ok(data[j * (pitch / 2) + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6067 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6068 data[j * (pitch / 2) + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6069 break;
6071 case MAKEFOURCC('N','V','1','2'):
6072 for (j = 0; j < ptr->height / 2; j++)
6073 for (k = 0; k < stride; k++)
6074 ok(data[j * pitch + k] == (((j + ptr->height) % 16) << 4) + (k % 16),
6075 "Unexpected byte %02x instead of %02x at test %d row %d column %d.\n",
6076 data[j * pitch + k], (((j + ptr->height) % 16) << 4) + (k % 16), i, j + ptr->height, k);
6077 break;
6079 default:
6083 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6084 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6086 ok(pitch == ptr->pitch, "%d: unexpected pitch %ld, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
6087 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
6089 ret = TRUE;
6090 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6091 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6092 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6094 IMF2DBuffer_Release(_2dbuffer);
6096 IMFMediaBuffer_Release(buffer);
6099 /* Alignment tests */
6100 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
6102 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
6104 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
6105 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6107 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6108 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6110 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6111 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6112 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6114 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6115 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6117 IMF2DBuffer_Release(_2dbuffer);
6118 IMFMediaBuffer_Release(buffer);
6122 static void test_MFCreateMediaBufferFromMediaType(void)
6124 static struct audio_buffer_test
6126 unsigned int duration;
6127 unsigned int min_length;
6128 unsigned int min_alignment;
6129 unsigned int block_alignment;
6130 unsigned int bytes_per_second;
6131 unsigned int buffer_length;
6132 } audio_tests[] =
6134 { 0, 0, 0, 4, 0, 20 },
6135 { 0, 16, 0, 4, 0, 20 },
6136 { 0, 0, 32, 4, 0, 36 },
6137 { 0, 64, 32, 4, 0, 64 },
6138 { 1, 0, 0, 4, 16, 36 },
6139 { 2, 0, 0, 4, 16, 52 },
6140 { 2, 0, 64, 4, 16, 68 },
6141 { 2, 0, 128, 4, 16,132 },
6143 IMFMediaType *media_type, *media_type2;
6144 unsigned int i, alignment;
6145 IMFMediaBuffer *buffer;
6146 DWORD length, max;
6147 BYTE *data;
6148 HRESULT hr;
6150 if (!pMFCreateMediaBufferFromMediaType)
6152 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6153 return;
6156 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6157 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6159 hr = MFCreateMediaType(&media_type);
6160 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6162 hr = MFCreateMediaType(&media_type2);
6163 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6165 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6166 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6168 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6169 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6171 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6173 const struct audio_buffer_test *ptr = &audio_tests[i];
6175 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6176 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6178 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6179 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6181 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6182 ptr->min_alignment, &buffer);
6183 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6184 if (FAILED(hr))
6185 break;
6187 check_interface(buffer, &IID_IMFGetService, FALSE);
6189 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6190 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6191 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6193 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6194 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6195 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6196 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6197 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6198 hr = IMFMediaBuffer_Unlock(buffer);
6199 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6201 IMFMediaBuffer_Release(buffer);
6203 /* Only major type is set. */
6204 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6205 ptr->min_alignment, &buffer);
6206 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6208 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6209 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6210 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6212 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6213 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6214 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6215 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6216 hr = IMFMediaBuffer_Unlock(buffer);
6217 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6219 IMFMediaBuffer_Release(buffer);
6222 IMFMediaType_Release(media_type);
6223 IMFMediaType_Release(media_type2);
6226 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6228 GUID guid, subtype;
6229 UINT32 value;
6230 HRESULT hr;
6232 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6233 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6234 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6236 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6237 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6239 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6241 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6242 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6244 if (fex->dwChannelMask)
6246 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6247 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6248 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6251 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6253 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6254 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6255 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6258 else
6260 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6261 subtype.Data1 = format->wFormatTag;
6262 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6264 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6265 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6266 ok(value, "Unexpected value.\n");
6269 if (format->nChannels)
6271 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6272 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6273 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6276 if (format->nSamplesPerSec)
6278 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6279 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6280 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6283 if (format->nAvgBytesPerSec)
6285 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6286 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6287 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6290 if (format->nBlockAlign)
6292 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6293 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6294 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6297 if (format->wBitsPerSample)
6299 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6300 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6301 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6304 /* Only set for uncompressed formats. */
6305 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6306 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6307 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6309 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6310 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6312 else
6313 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6316 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6318 static const WAVEFORMATEX waveformatex_tests[] =
6320 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6321 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6322 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6323 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6324 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6325 { 1234, 0, 0, 0, 0, 0 },
6326 { WAVE_FORMAT_ALAW },
6327 { WAVE_FORMAT_CREATIVE_ADPCM },
6328 { WAVE_FORMAT_MPEGLAYER3 },
6329 { WAVE_FORMAT_MPEG_ADTS_AAC },
6330 { WAVE_FORMAT_ALAC },
6331 { WAVE_FORMAT_AMR_NB },
6332 { WAVE_FORMAT_AMR_WB },
6333 { WAVE_FORMAT_AMR_WP },
6334 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6335 { WAVE_FORMAT_DRM },
6336 { WAVE_FORMAT_DTS },
6337 { WAVE_FORMAT_FLAC },
6338 { WAVE_FORMAT_MPEG },
6339 { WAVE_FORMAT_WMAVOICE9 },
6340 { WAVE_FORMAT_OPUS },
6341 { WAVE_FORMAT_WMAUDIO2 },
6342 { WAVE_FORMAT_WMAUDIO3 },
6343 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6344 { WAVE_FORMAT_WMASPDIF },
6347 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6348 WAVEFORMATEXTENSIBLE waveformatext;
6349 MPEGLAYER3WAVEFORMAT mp3format;
6350 IMFMediaType *mediatype;
6351 unsigned int i, size;
6352 HRESULT hr;
6354 hr = MFCreateMediaType(&mediatype);
6355 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6357 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6359 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6360 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6362 validate_media_type(mediatype, &waveformatex_tests[i]);
6364 waveformatext.Format = waveformatex_tests[i];
6365 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6366 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6367 waveformatext.Samples.wSamplesPerBlock = 123;
6368 waveformatext.dwChannelMask = 0x8;
6369 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6370 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6372 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6373 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6375 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6376 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6378 validate_media_type(mediatype, &waveformatext.Format);
6381 /* MPEGLAYER3WAVEFORMAT */
6382 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6383 mp3format.wfx.nChannels = 2;
6384 mp3format.wfx.nSamplesPerSec = 44100;
6385 mp3format.wfx.nAvgBytesPerSec = 16000;
6386 mp3format.wfx.nBlockAlign = 1;
6387 mp3format.wfx.wBitsPerSample = 0;
6388 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6389 mp3format.wID = MPEGLAYER3_ID_MPEG;
6390 mp3format.fdwFlags = 0;
6391 mp3format.nBlockSize = 417;
6392 mp3format.nFramesPerBlock = 0;
6393 mp3format.nCodecDelay = 0;
6395 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6396 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6398 validate_media_type(mediatype, &mp3format.wfx);
6399 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6400 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6401 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6402 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6404 IMFMediaType_Release(mediatype);
6407 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
6409 MFVIDEOFORMAT *video_format;
6410 IMFMediaType *media_type;
6411 UINT32 size;
6412 HRESULT hr;
6414 hr = MFCreateMediaType(&media_type);
6415 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6417 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
6418 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6419 ok(!!video_format, "Unexpected format.\n");
6420 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
6421 CoTaskMemFree(video_format);
6423 IMFMediaType_Release(media_type);
6426 static void test_MFCreateDXSurfaceBuffer(void)
6428 IDirect3DSurface9 *backbuffer = NULL, *surface;
6429 IDirect3DSwapChain9 *swapchain;
6430 D3DLOCKED_RECT locked_rect;
6431 DWORD length, max_length;
6432 IDirect3DDevice9 *device;
6433 IMF2DBuffer2 *_2dbuffer2;
6434 BOOL value, broken_test;
6435 IMFMediaBuffer *buffer;
6436 IMF2DBuffer *_2dbuffer;
6437 BYTE *data, *data2;
6438 IMFGetService *gs;
6439 IDirect3D9 *d3d;
6440 HWND window;
6441 HRESULT hr;
6442 LONG pitch;
6444 if (!pMFCreateDXSurfaceBuffer)
6446 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
6447 return;
6450 window = create_window();
6451 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6452 ok(!!d3d, "Failed to create a D3D object.\n");
6453 if (!(device = create_d3d9_device(d3d, window)))
6455 skip("Failed to create a D3D device, skipping tests.\n");
6456 goto done;
6459 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
6460 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
6462 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6463 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
6464 ok(backbuffer != NULL, "The back buffer is NULL\n");
6466 IDirect3DSwapChain9_Release(swapchain);
6468 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
6469 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6471 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
6472 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6474 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6475 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6476 check_interface(buffer, &IID_IMFGetService, TRUE);
6478 /* Surface is accessible. */
6479 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
6480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6481 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
6482 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6483 ok(surface == backbuffer, "Unexpected surface pointer.\n");
6484 IDirect3DSurface9_Release(surface);
6485 IMFGetService_Release(gs);
6487 max_length = 0;
6488 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6489 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6490 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6492 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6493 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6494 ok(!length, "Unexpected length %lu.\n", length);
6496 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6497 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6499 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6500 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6501 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
6503 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6504 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6506 /* Cannot lock while the surface is locked. */
6507 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6508 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6510 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6511 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6513 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6514 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6515 /* Broken on Windows 8 and 10 v1507 */
6516 broken_test = length == 0;
6517 ok(length == max_length || broken(broken_test), "Unexpected length %lu instead of %lu.\n", length, max_length);
6519 /* You can lock the surface while the media buffer is locked. */
6520 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6521 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6523 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6526 hr = IMFMediaBuffer_Unlock(buffer);
6527 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6529 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6530 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6532 /* Unlock twice. */
6533 hr = IMFMediaBuffer_Unlock(buffer);
6534 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6536 hr = IMFMediaBuffer_Unlock(buffer);
6537 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6539 /* Lock twice. */
6540 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6541 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6543 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6544 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6545 ok(data == data2, "Unexpected pointer.\n");
6547 hr = IMFMediaBuffer_Unlock(buffer);
6548 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6550 hr = IMFMediaBuffer_Unlock(buffer);
6551 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6553 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6554 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6556 /* Unlocked. */
6557 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6558 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6560 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6561 ok(hr == S_OK, "Failed to lock back buffer, hr %#lx.\n", hr);
6563 /* Cannot lock the buffer while the surface is locked. */
6564 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6565 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6567 hr = IDirect3DSurface9_UnlockRect(backbuffer);
6568 ok(hr == S_OK, "Failed to unlock back buffer, hr %#lx.\n", hr);
6570 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6571 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6573 /* Cannot lock the surface once the buffer is locked. */
6574 hr = IDirect3DSurface9_LockRect(backbuffer, &locked_rect, NULL, 0);
6575 ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#lx.\n", hr);
6577 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6580 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6581 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6583 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6584 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6586 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6587 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6589 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6592 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6593 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6595 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6597 ok(!value, "Unexpected return value %d.\n", value);
6599 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6600 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6601 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6603 ok(length == max_length, "Unexpected length %lu.\n", length);
6605 IMF2DBuffer_Release(_2dbuffer);
6607 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6610 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6611 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6612 ok(data == data2, "Unexpected scanline pointer.\n");
6613 memset(data, 0xab, 4);
6614 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6616 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6617 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6618 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6619 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6621 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6622 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6623 ok(data[0] == 0xab || broken(broken_test), "Unexpected leading byte.\n");
6624 hr = IMFMediaBuffer_Unlock(buffer);
6625 ok(hr == S_OK || broken(broken_test), "Unexpected hr %#lx.\n", hr);
6627 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6628 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6629 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6631 IMF2DBuffer2_Release(_2dbuffer2);
6633 IMFMediaBuffer_Release(buffer);
6634 IDirect3DDevice9_Release(device);
6636 done:
6637 if (backbuffer)
6638 IDirect3DSurface9_Release(backbuffer);
6639 ok(!IDirect3D9_Release(d3d), "Unexpected refcount.\n");
6640 DestroyWindow(window);
6643 static void test_MFCreateTrackedSample(void)
6645 IMFTrackedSample *tracked_sample;
6646 IMFSample *sample;
6647 IUnknown *unk;
6648 HRESULT hr;
6650 if (!pMFCreateTrackedSample)
6652 win_skip("MFCreateTrackedSample() is not available.\n");
6653 return;
6656 hr = pMFCreateTrackedSample(&tracked_sample);
6657 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6659 /* It's actually a sample. */
6660 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6661 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6663 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6664 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6665 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6666 IUnknown_Release(unk);
6668 IMFSample_Release(sample);
6670 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6672 IMFTrackedSample_Release(tracked_sample);
6675 static void test_MFFrameRateToAverageTimePerFrame(void)
6677 static const struct frame_rate_test
6679 unsigned int numerator;
6680 unsigned int denominator;
6681 UINT64 avgtime;
6682 } frame_rate_tests[] =
6684 { 60000, 1001, 166833 },
6685 { 30000, 1001, 333667 },
6686 { 24000, 1001, 417188 },
6687 { 60, 1, 166667 },
6688 { 30, 1, 333333 },
6689 { 50, 1, 200000 },
6690 { 25, 1, 400000 },
6691 { 24, 1, 416667 },
6693 { 39, 1, 256410 },
6694 { 120, 1, 83333 },
6696 unsigned int i;
6697 UINT64 avgtime;
6698 HRESULT hr;
6700 avgtime = 1;
6701 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6702 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6703 ok(!avgtime, "Unexpected frame time.\n");
6705 avgtime = 1;
6706 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6707 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6708 ok(!avgtime, "Unexpected frame time.\n");
6710 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6712 avgtime = 0;
6713 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6714 frame_rate_tests[i].denominator, &avgtime);
6715 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6716 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6717 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6721 static void test_MFAverageTimePerFrameToFrameRate(void)
6723 static const struct frame_rate_test
6725 unsigned int numerator;
6726 unsigned int denominator;
6727 UINT64 avgtime;
6728 } frame_rate_tests[] =
6730 { 60000, 1001, 166833 },
6731 { 30000, 1001, 333667 },
6732 { 24000, 1001, 417188 },
6733 { 60, 1, 166667 },
6734 { 30, 1, 333333 },
6735 { 50, 1, 200000 },
6736 { 25, 1, 400000 },
6737 { 24, 1, 416667 },
6739 { 1000000, 25641, 256410 },
6740 { 10000000, 83333, 83333 },
6741 { 1, 10, 100000000 },
6742 { 1, 10, 100000001 },
6743 { 1, 10, 200000000 },
6744 { 1, 1, 10000000 },
6745 { 1, 2, 20000000 },
6746 { 5, 1, 2000000 },
6747 { 10, 1, 1000000 },
6749 unsigned int i, numerator, denominator;
6750 HRESULT hr;
6752 numerator = denominator = 1;
6753 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
6754 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6755 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
6757 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6759 numerator = denominator = 12345;
6760 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
6761 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6762 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
6763 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
6764 frame_rate_tests[i].denominator);
6768 static void test_MFMapDXGIFormatToDX9Format(void)
6770 static const struct format_pair
6772 DXGI_FORMAT dxgi_format;
6773 DWORD d3d9_format;
6775 formats_map[] =
6777 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6778 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6779 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6780 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6781 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6782 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6783 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6784 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6785 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6786 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6787 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6788 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6789 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6790 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6791 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6792 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6793 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6794 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6795 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6796 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6797 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6798 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6799 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6800 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6801 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6802 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6803 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6804 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6805 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6806 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6807 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6808 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6809 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6810 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6811 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6812 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6813 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6814 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6815 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6816 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6817 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6818 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6819 { DXGI_FORMAT_P8, D3DFMT_P8 },
6820 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6822 unsigned int i;
6823 DWORD format;
6825 if (!pMFMapDXGIFormatToDX9Format)
6827 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6828 return;
6831 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6833 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6834 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6838 static void test_MFMapDX9FormatToDXGIFormat(void)
6840 static const struct format_pair
6842 DXGI_FORMAT dxgi_format;
6843 DWORD d3d9_format;
6845 formats_map[] =
6847 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6848 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6849 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6850 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6851 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6852 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6853 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6854 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6855 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6856 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6857 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6858 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6859 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6860 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6861 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6862 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6863 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6864 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6865 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6866 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6867 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6868 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6869 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6870 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6871 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6872 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6873 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6874 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6875 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6876 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6877 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6878 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6879 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6880 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6881 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6882 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6883 { DXGI_FORMAT_P8, D3DFMT_P8 },
6884 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6886 DXGI_FORMAT format;
6887 unsigned int i;
6889 if (!pMFMapDX9FormatToDXGIFormat)
6891 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6892 return;
6895 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6897 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6898 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
6899 format, formats_map[i].d3d9_format);
6903 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6904 REFIID riid, void **obj)
6906 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6907 IsEqualIID(riid, &IID_IUnknown))
6909 *obj = iface;
6910 IMFVideoSampleAllocatorNotify_AddRef(iface);
6911 return S_OK;
6914 *obj = NULL;
6915 return E_NOINTERFACE;
6918 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6920 return 2;
6923 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6925 return 1;
6928 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6930 return E_NOTIMPL;
6933 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6935 test_notify_callback_QueryInterface,
6936 test_notify_callback_AddRef,
6937 test_notify_callback_Release,
6938 test_notify_callback_NotifyRelease,
6941 static IMFMediaType * create_video_type(const GUID *subtype)
6943 IMFMediaType *video_type;
6944 HRESULT hr;
6946 hr = MFCreateMediaType(&video_type);
6947 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6949 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6950 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6952 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6953 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6955 return video_type;
6958 static ID3D11Device *create_d3d11_device(void)
6960 static const D3D_FEATURE_LEVEL default_feature_level[] =
6962 D3D_FEATURE_LEVEL_11_0,
6963 D3D_FEATURE_LEVEL_10_1,
6964 D3D_FEATURE_LEVEL_10_0,
6966 const D3D_FEATURE_LEVEL *feature_level;
6967 unsigned int feature_level_count;
6968 ID3D11Device *device;
6970 feature_level = default_feature_level;
6971 feature_level_count = ARRAY_SIZE(default_feature_level);
6973 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6974 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6975 return device;
6976 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6977 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6978 return device;
6979 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6980 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6981 return device;
6983 return NULL;
6986 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
6987 const BYTE *data, unsigned int src_pitch)
6989 ID3D11DeviceContext *immediate_context;
6990 ID3D11Device *device;
6992 ID3D11Texture2D_GetDevice(texture, &device);
6993 ID3D11Device_GetImmediateContext(device, &immediate_context);
6995 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
6996 sub_resource_idx, NULL, data, src_pitch, 0);
6998 ID3D11DeviceContext_Release(immediate_context);
6999 ID3D11Device_Release(device);
7002 static ID3D12Device *create_d3d12_device(void)
7004 ID3D12Device *device;
7005 HRESULT hr;
7007 if (!pD3D12CreateDevice) return NULL;
7009 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
7010 if (FAILED(hr))
7011 return NULL;
7013 return device;
7016 static void test_d3d11_surface_buffer(void)
7018 DWORD max_length, cur_length, length, color;
7019 IMFDXGIBuffer *dxgi_buffer;
7020 D3D11_TEXTURE2D_DESC desc;
7021 ID3D11Texture2D *texture;
7022 IMF2DBuffer *_2d_buffer;
7023 IMFMediaBuffer *buffer;
7024 ID3D11Device *device;
7025 BYTE buff[64 * 64 * 4];
7026 BYTE *data, *data2;
7027 LONG pitch, pitch2;
7028 UINT index, size;
7029 IUnknown *obj;
7030 HRESULT hr;
7032 if (!pMFCreateDXGISurfaceBuffer)
7034 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
7035 return;
7038 /* d3d11 */
7039 if (!(device = create_d3d11_device()))
7041 skip("Failed to create a D3D11 device, skipping tests.\n");
7042 return;
7045 memset(&desc, 0, sizeof(desc));
7046 desc.Width = 64;
7047 desc.Height = 64;
7048 desc.ArraySize = 1;
7049 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7050 desc.SampleDesc.Count = 1;
7051 desc.SampleDesc.Quality = 0;
7053 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7054 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7056 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
7057 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7059 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7060 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7061 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7062 check_interface(buffer, &IID_IMFGetService, FALSE);
7064 max_length = 0;
7065 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
7066 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7067 ok(!!max_length, "Unexpected length %lu.\n", max_length);
7069 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7070 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7071 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
7073 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
7074 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7076 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
7077 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
7078 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
7080 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7081 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7083 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
7084 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7085 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
7086 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7087 ok(length == max_length, "Unexpected length %lu.\n", length);
7088 IMF2DBuffer_Release(_2d_buffer);
7090 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7091 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7093 EXPECT_REF(texture, 2);
7094 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
7095 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7096 EXPECT_REF(texture, 3);
7097 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
7098 IUnknown_Release(obj);
7100 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
7101 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7103 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
7104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7105 ok(index == 0, "Unexpected subresource index.\n");
7107 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7108 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7110 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7111 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7113 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7114 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7116 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7117 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7119 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7120 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7121 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7122 IUnknown_Release(obj);
7124 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7125 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7127 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7128 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7130 IMFDXGIBuffer_Release(dxgi_buffer);
7132 /* Texture updates. */
7133 color = get_d3d11_texture_color(texture, 0, 0);
7134 ok(!color, "Unexpected texture color %#lx.\n", color);
7136 max_length = cur_length = 0;
7137 data = NULL;
7138 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7139 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7140 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7141 if (data) *(DWORD *)data = ~0u;
7143 color = get_d3d11_texture_color(texture, 0, 0);
7144 ok(!color, "Unexpected texture color %#lx.\n", color);
7146 hr = IMFMediaBuffer_Unlock(buffer);
7147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7149 color = get_d3d11_texture_color(texture, 0, 0);
7150 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7152 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7153 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7154 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7156 hr = IMFMediaBuffer_Unlock(buffer);
7157 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7159 /* Lock2D()/Unlock2D() */
7160 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7163 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7164 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7166 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7167 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7168 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7170 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7172 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7174 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7176 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7178 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7179 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7181 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7182 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7184 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7185 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7187 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7188 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7190 IMF2DBuffer_Release(_2d_buffer);
7191 IMFMediaBuffer_Release(buffer);
7193 /* Bottom up. */
7194 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7195 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7197 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7198 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7200 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7201 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7202 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7204 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7205 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7206 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7208 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7209 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7211 IMF2DBuffer_Release(_2d_buffer);
7212 IMFMediaBuffer_Release(buffer);
7214 ID3D11Texture2D_Release(texture);
7216 /* Subresource index 1. */
7217 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7218 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7220 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
7221 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7223 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7224 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7226 /* Pitch reflects top level. */
7227 memset(buff, 0, sizeof(buff));
7228 *(DWORD *)buff = 0xff00ff00;
7229 update_d3d11_texture(texture, 1, buff, 64 * 4);
7231 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7232 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7233 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7234 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
7236 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7237 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7239 IMF2DBuffer_Release(_2d_buffer);
7240 IMFMediaBuffer_Release(buffer);
7242 ID3D11Texture2D_Release(texture);
7244 ID3D11Device_Release(device);
7247 static void test_d3d12_surface_buffer(void)
7249 IMFDXGIBuffer *dxgi_buffer;
7250 D3D12_HEAP_PROPERTIES heap_props;
7251 D3D12_RESOURCE_DESC desc;
7252 ID3D12Resource *resource;
7253 IMFMediaBuffer *buffer;
7254 unsigned int refcount;
7255 ID3D12Device *device;
7256 IUnknown *obj;
7257 HRESULT hr;
7259 /* d3d12 */
7260 if (!(device = create_d3d12_device()))
7262 skip("Failed to create a D3D12 device, skipping tests.\n");
7263 return;
7266 memset(&heap_props, 0, sizeof(heap_props));
7267 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
7269 memset(&desc, 0, sizeof(desc));
7270 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7271 desc.Alignment = 0;
7272 desc.Width = 32;
7273 desc.Height = 32;
7274 desc.DepthOrArraySize = 1;
7275 desc.MipLevels = 1;
7276 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7277 desc.SampleDesc.Count = 1;
7278 desc.SampleDesc.Quality = 0;
7279 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7280 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
7282 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
7283 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
7284 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7286 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
7287 if (hr == E_INVALIDARG)
7289 todo_wine
7290 win_skip("D3D12 resource buffers are not supported.\n");
7291 goto notsupported;
7293 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7295 if (SUCCEEDED(hr))
7297 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7298 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7299 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7300 check_interface(buffer, &IID_IMFGetService, FALSE);
7302 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7303 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7305 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
7306 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7307 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
7308 IUnknown_Release(obj);
7310 IMFDXGIBuffer_Release(dxgi_buffer);
7311 IMFMediaBuffer_Release(buffer);
7314 notsupported:
7315 ID3D12Resource_Release(resource);
7316 refcount = ID3D12Device_Release(device);
7317 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
7320 static void test_sample_allocator_sysmem(void)
7322 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
7323 IMFMediaType *media_type, *video_type, *video_type2;
7324 IMFVideoSampleAllocatorCallback *allocator_cb;
7325 IMFVideoSampleAllocatorEx *allocatorex;
7326 IMFVideoSampleAllocator *allocator;
7327 IMFSample *sample, *sample2;
7328 IMFAttributes *attributes;
7329 IMFMediaBuffer *buffer;
7330 LONG refcount, count;
7331 DWORD buffer_count;
7332 IUnknown *unk;
7333 HRESULT hr;
7335 if (!pMFCreateVideoSampleAllocatorEx)
7336 return;
7338 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
7339 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7341 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
7342 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
7343 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
7345 IUnknown_Release(unk);
7347 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7348 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7350 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7353 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7356 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
7357 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7359 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7360 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7362 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
7363 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7365 count = 10;
7366 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7367 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7368 ok(!count, "Unexpected count %ld.\n", count);
7370 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7371 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7373 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7374 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7376 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
7377 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7379 hr = MFCreateMediaType(&media_type);
7380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7382 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
7383 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7385 video_type = create_video_type(&MFVideoFormat_RGB32);
7386 video_type2 = create_video_type(&MFVideoFormat_RGB32);
7388 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7389 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7391 /* Frame size is required. */
7392 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7393 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7395 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7396 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7398 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
7399 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7401 EXPECT_REF(video_type, 1);
7402 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7403 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7404 EXPECT_REF(video_type, 2);
7406 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
7407 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7409 /* Setting identical type does not replace it. */
7410 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7411 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7412 EXPECT_REF(video_type, 2);
7413 EXPECT_REF(video_type2, 1);
7415 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7416 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7418 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7420 EXPECT_REF(video_type2, 2);
7421 EXPECT_REF(video_type, 1);
7423 /* Modify referenced type. */
7424 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
7425 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7427 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7428 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7429 EXPECT_REF(video_type, 2);
7430 EXPECT_REF(video_type2, 1);
7432 count = 0;
7433 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7435 ok(count == 1, "Unexpected count %ld.\n", count);
7437 sample = NULL;
7438 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7440 refcount = get_refcount(sample);
7442 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7443 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7444 ok(!count, "Unexpected count %ld.\n", count);
7446 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
7447 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7449 /* Reinitialize with active sample. */
7450 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7452 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
7453 EXPECT_REF(video_type, 2);
7455 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7456 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7457 todo_wine
7458 ok(!count, "Unexpected count %ld.\n", count);
7460 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7461 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7463 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7464 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7466 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7467 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7468 check_interface(buffer, &IID_IMFGetService, TRUE);
7469 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7471 IMFMediaBuffer_Release(buffer);
7473 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7475 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
7477 IMFSample_Release(sample);
7479 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7481 todo_wine
7482 EXPECT_REF(video_type, 2);
7484 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7486 ok(!count, "Unexpected count %ld.\n", count);
7488 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7489 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7491 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7492 IMFVideoSampleAllocator_Release(allocator);
7494 /* IMFVideoSampleAllocatorEx */
7495 hr = MFCreateAttributes(&attributes, 0);
7496 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7498 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7499 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7501 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7502 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7504 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
7505 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7507 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
7508 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7510 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7511 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7513 EXPECT_REF(attributes, 1);
7514 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7515 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7516 EXPECT_REF(attributes, 2);
7518 count = 0;
7519 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7520 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7521 ok(count == 1, "Unexpected count %ld.\n", count);
7523 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7526 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7527 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7528 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
7530 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7531 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7533 /* Reinitialize with already allocated samples. */
7534 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
7535 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7536 EXPECT_REF(attributes, 1);
7538 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7539 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7540 IMFSample_Release(sample2);
7542 IMFSample_Release(sample);
7544 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7545 IMFVideoSampleAllocatorEx_Release(allocatorex);
7546 IMFAttributes_Release(attributes);
7549 static void test_sample_allocator_d3d9(void)
7551 IDirect3DDeviceManager9 *d3d9_manager;
7552 IMFVideoSampleAllocator *allocator;
7553 IDirect3DDevice9 *d3d9_device;
7554 IMFMediaType *video_type;
7555 IMFMediaBuffer *buffer;
7556 unsigned int token;
7557 IMFSample *sample;
7558 IDirect3D9 *d3d9;
7559 HWND window;
7560 HRESULT hr;
7562 if (!pMFCreateVideoSampleAllocatorEx)
7563 return;
7565 window = create_window();
7566 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7567 ok(!!d3d9, "Failed to create a D3D9 object.\n");
7568 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
7570 skip("Failed to create a D3D9 device, skipping tests.\n");
7571 goto done;
7574 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
7575 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7577 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
7578 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7580 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7581 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7583 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
7584 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7586 video_type = create_video_type(&MFVideoFormat_RGB32);
7588 /* Frame size is required. */
7589 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7590 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7592 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7593 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7595 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7596 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7598 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7599 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7601 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7604 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7605 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7606 check_interface(buffer, &IID_IMFGetService, TRUE);
7607 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7609 IMFSample_Release(sample);
7610 IMFMediaBuffer_Release(buffer);
7612 IMFVideoSampleAllocator_Release(allocator);
7613 IMFMediaType_Release(video_type);
7614 IDirect3DDeviceManager9_Release(d3d9_manager);
7615 IDirect3DDevice9_Release(d3d9_device);
7617 done:
7618 IDirect3D9_Release(d3d9);
7619 DestroyWindow(window);
7622 static void test_sample_allocator_d3d11(void)
7624 IMFMediaType *video_type;
7625 IMFVideoSampleAllocatorEx *allocatorex;
7626 IMFVideoSampleAllocator *allocator;
7627 unsigned int i, token;
7628 IMFDXGIDeviceManager *manager;
7629 IMFSample *sample;
7630 IMFDXGIBuffer *dxgi_buffer;
7631 IMFAttributes *attributes;
7632 D3D11_TEXTURE2D_DESC desc;
7633 ID3D11Texture2D *texture;
7634 IMFMediaBuffer *buffer;
7635 ID3D11Device *device;
7636 HRESULT hr;
7637 BYTE *data;
7638 static const unsigned int usage[] =
7640 D3D11_USAGE_DEFAULT,
7641 D3D11_USAGE_IMMUTABLE,
7642 D3D11_USAGE_DYNAMIC,
7643 D3D11_USAGE_STAGING,
7644 D3D11_USAGE_STAGING + 1,
7646 static const unsigned int sharing[] =
7648 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7649 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7650 D3D11_RESOURCE_MISC_SHARED,
7653 if (!pMFCreateVideoSampleAllocatorEx)
7654 return;
7656 if (!(device = create_d3d11_device()))
7658 skip("Failed to create a D3D11 device, skipping tests.\n");
7659 return;
7662 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7663 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7665 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7666 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
7668 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7669 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7671 EXPECT_REF(manager, 1);
7672 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
7673 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7674 EXPECT_REF(manager, 2);
7676 video_type = create_video_type(&MFVideoFormat_RGB32);
7677 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7678 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7680 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7681 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7683 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7684 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7686 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7687 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7689 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7690 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7691 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7692 check_interface(buffer, &IID_IMFGetService, FALSE);
7694 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7695 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7697 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7698 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7700 ID3D11Texture2D_GetDesc(texture, &desc);
7701 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
7702 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
7703 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
7704 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
7705 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
7706 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
7707 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
7708 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
7709 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7710 desc.BindFlags);
7711 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7712 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7714 ID3D11Texture2D_Release(texture);
7715 IMFDXGIBuffer_Release(dxgi_buffer);
7717 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7718 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7720 hr = IMFMediaBuffer_Unlock(buffer);
7721 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7723 IMFMediaBuffer_Release(buffer);
7724 IMFSample_Release(sample);
7726 IMFVideoSampleAllocator_Release(allocator);
7728 /* MF_SA_D3D11_USAGE */
7729 hr = MFCreateAttributes(&attributes, 1);
7730 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
7732 for (i = 0; i < ARRAY_SIZE(usage); ++i)
7734 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7735 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7737 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7738 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7740 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
7741 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7743 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7744 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
7746 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7747 IMFVideoSampleAllocatorEx_Release(allocatorex);
7748 continue;
7750 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
7752 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7753 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7755 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7756 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7758 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7759 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7761 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7762 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7764 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7765 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7767 ID3D11Texture2D_GetDesc(texture, &desc);
7768 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
7769 if (usage[i] == D3D11_USAGE_DEFAULT)
7771 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7772 desc.BindFlags);
7773 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7775 else if (usage[i] == D3D11_USAGE_DYNAMIC)
7777 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
7778 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7780 else if (usage[i] == D3D11_USAGE_STAGING)
7782 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
7783 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
7784 desc.CPUAccessFlags);
7786 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7788 ID3D11Texture2D_Release(texture);
7789 IMFDXGIBuffer_Release(dxgi_buffer);
7790 IMFMediaBuffer_Release(buffer);
7792 IMFSample_Release(sample);
7794 IMFVideoSampleAllocatorEx_Release(allocatorex);
7797 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
7798 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
7800 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7801 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7803 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7804 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7806 hr = IMFAttributes_DeleteAllItems(attributes);
7807 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7809 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7810 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7812 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
7814 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
7815 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7818 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
7820 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
7821 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7824 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7825 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
7827 todo_wine
7828 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
7829 IMFVideoSampleAllocatorEx_Release(allocatorex);
7830 continue;
7832 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
7834 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7835 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7837 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7838 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7840 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7841 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7843 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7844 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7846 ID3D11Texture2D_GetDesc(texture, &desc);
7847 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
7849 ID3D11Texture2D_Release(texture);
7850 IMFDXGIBuffer_Release(dxgi_buffer);
7851 IMFMediaBuffer_Release(buffer);
7853 IMFSample_Release(sample);
7855 IMFVideoSampleAllocatorEx_Release(allocatorex);
7858 IMFAttributes_Release(attributes);
7860 IMFDXGIDeviceManager_Release(manager);
7861 ID3D11Device_Release(device);
7864 static void test_sample_allocator_d3d12(void)
7866 IMFVideoSampleAllocator *allocator = NULL;
7867 D3D12_HEAP_PROPERTIES heap_props;
7868 IMFDXGIDeviceManager *manager;
7869 D3D12_HEAP_FLAGS heap_flags;
7870 IMFDXGIBuffer *dxgi_buffer;
7871 IMFMediaType *video_type;
7872 ID3D12Resource *resource;
7873 D3D12_RESOURCE_DESC desc;
7874 IMFMediaBuffer *buffer;
7875 ID3D12Device *device;
7876 unsigned int token;
7877 IMFSample *sample;
7878 HRESULT hr;
7880 if (!(device = create_d3d12_device()))
7882 skip("Failed to create a D3D12 device, skipping tests.\n");
7883 return;
7886 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7887 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7889 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7890 if (FAILED(hr))
7892 win_skip("Device manager does not support D3D12 devices.\n");
7893 goto done;
7895 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
7897 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7898 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7900 EXPECT_REF(manager, 1);
7901 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
7902 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7903 EXPECT_REF(manager, 2);
7905 video_type = create_video_type(&MFVideoFormat_RGB32);
7906 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7907 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7908 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
7909 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7911 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7912 todo_wine
7913 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
7914 if (FAILED(hr)) goto done;
7916 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7917 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7919 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7920 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7922 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7923 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7924 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7925 check_interface(buffer, &IID_IMFGetService, FALSE);
7927 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7928 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7930 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
7931 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7933 resource->lpVtbl->GetDesc(resource, &desc);
7934 ok(desc.Width == 64, "Unexpected width.\n");
7935 ok(desc.Height == 64, "Unexpected height.\n");
7936 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
7937 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
7938 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
7939 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
7940 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
7941 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
7942 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
7944 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
7945 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7946 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
7947 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
7948 heap_props.CPUPageProperty);
7949 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
7950 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
7952 ID3D12Resource_Release(resource);
7953 IMFDXGIBuffer_Release(dxgi_buffer);
7954 IMFMediaBuffer_Release(buffer);
7955 IMFSample_Release(sample);
7957 done:
7958 if (allocator)
7959 IMFVideoSampleAllocator_Release(allocator);
7960 IMFDXGIDeviceManager_Release(manager);
7961 ID3D12Device_Release(device);
7964 static void test_MFLockSharedWorkQueue(void)
7966 DWORD taskid, queue, queue2;
7967 HRESULT hr;
7969 if (!pMFLockSharedWorkQueue)
7971 win_skip("MFLockSharedWorkQueue() is not available.\n");
7972 return;
7975 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
7976 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
7978 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
7979 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7981 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
7982 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7984 taskid = 0;
7985 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
7986 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7988 queue = 0;
7989 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
7990 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
7992 queue2 = 0;
7993 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
7994 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7995 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
7997 hr = MFUnlockWorkQueue(queue2);
7998 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8000 hr = MFUnlockWorkQueue(queue);
8001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8003 hr = MFShutdown();
8004 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
8007 static void test_MFllMulDiv(void)
8009 /* (a * b + d) / c */
8010 static const struct muldivtest
8012 LONGLONG a;
8013 LONGLONG b;
8014 LONGLONG c;
8015 LONGLONG d;
8016 LONGLONG result;
8018 muldivtests[] =
8020 { 0, 0, 0, 0, _I64_MAX },
8021 { 1000000, 1000000, 2, 0, 500000000000 },
8022 { _I64_MAX, 3, _I64_MAX, 0, 3 },
8023 { _I64_MAX, 3, _I64_MAX, 1, 3 },
8024 { -10000, 3, 100, 0, -300 },
8025 { 2, 0, 3, 5, 1 },
8026 { 2, 1, 1, -3, -1 },
8027 /* a * b product does not fit in uint64_t */
8028 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
8029 /* Large a * b product, large denominator */
8030 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
8032 unsigned int i;
8034 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
8036 LONGLONG result;
8038 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
8039 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
8040 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
8044 static void test_shared_dxgi_device_manager(void)
8046 IMFDXGIDeviceManager *manager;
8047 HRESULT hr;
8048 UINT token;
8050 if (!pMFLockDXGIDeviceManager)
8052 win_skip("Shared DXGI device manager is not supported.\n");
8053 return;
8056 hr = pMFUnlockDXGIDeviceManager();
8057 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8059 manager = NULL;
8060 hr = pMFLockDXGIDeviceManager(NULL, &manager);
8061 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8062 ok(!!manager, "Unexpected instance.\n");
8064 hr = pMFLockDXGIDeviceManager(&token, &manager);
8065 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8067 EXPECT_REF(manager, 3);
8069 hr = pMFUnlockDXGIDeviceManager();
8070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8072 EXPECT_REF(manager, 2);
8074 hr = pMFUnlockDXGIDeviceManager();
8075 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8078 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
8079 DWORD d3dformat)
8081 unsigned int transfer_function;
8082 GUID guid;
8084 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
8086 switch (d3dformat)
8088 case D3DFMT_X8R8G8B8:
8089 case D3DFMT_R8G8B8:
8090 case D3DFMT_A8R8G8B8:
8091 case D3DFMT_R5G6B5:
8092 case D3DFMT_X1R5G5B5:
8093 case D3DFMT_A2B10G10R10:
8094 case D3DFMT_P8:
8095 transfer_function = MFVideoTransFunc_sRGB;
8096 break;
8097 default:
8098 transfer_function = MFVideoTransFunc_10;
8101 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
8102 guid.Data1 = d3dformat;
8104 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
8105 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
8106 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
8107 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
8108 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8109 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8110 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8111 format->videoInfo.InterlaceMode);
8112 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8113 format->videoInfo.TransferFunction);
8114 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8115 format->videoInfo.ColorPrimaries);
8116 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8117 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8118 format->videoInfo.SourceLighting);
8119 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8120 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8121 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8122 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8123 format->videoInfo.NominalRange);
8124 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8125 "Unexpected geometric aperture.\n");
8126 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8127 "Unexpected minimum display aperture.\n");
8128 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8129 "Unexpected geometric aperture.\n");
8130 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8131 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8132 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8133 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8134 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8135 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8136 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8139 static void test_MFInitVideoFormat_RGB(void)
8141 static const DWORD formats[] =
8143 0, /* same D3DFMT_X8R8G8B8 */
8144 D3DFMT_X8R8G8B8,
8145 D3DFMT_R8G8B8,
8146 D3DFMT_A8R8G8B8,
8147 D3DFMT_R5G6B5,
8148 D3DFMT_X1R5G5B5,
8149 D3DFMT_A2B10G10R10,
8150 D3DFMT_P8,
8151 D3DFMT_L8,
8152 D3DFMT_YUY2,
8153 D3DFMT_DXT1,
8154 D3DFMT_D16,
8155 D3DFMT_L16,
8156 D3DFMT_A16B16G16R16F,
8158 MFVIDEOFORMAT format;
8159 unsigned int i;
8160 HRESULT hr;
8162 if (!pMFInitVideoFormat_RGB)
8164 win_skip("MFInitVideoFormat_RGB is not available.\n");
8165 return;
8168 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
8169 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8171 for (i = 0; i < ARRAY_SIZE(formats); ++i)
8173 memset(&format, 0, sizeof(format));
8174 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
8175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8176 if (SUCCEEDED(hr))
8177 check_video_format(&format, 64, 32, formats[i]);
8181 START_TEST(mfplat)
8183 char **argv;
8184 int argc;
8186 init_functions();
8188 argc = winetest_get_mainargs(&argv);
8189 if (argc >= 3)
8191 test_queue_com_state(argv[2]);
8192 return;
8195 if (!pMFCreateVideoSampleAllocatorEx)
8196 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
8198 if (!pD3D12CreateDevice)
8199 skip("Missing d3d12 support, some tests will be skipped.\n");
8201 CoInitialize(NULL);
8203 test_startup();
8204 test_register();
8205 test_media_type();
8206 test_MFCreateMediaEvent();
8207 test_attributes();
8208 test_sample();
8209 test_file_stream();
8210 test_MFCreateMFByteStreamOnStream();
8211 test_system_memory_buffer();
8212 test_system_memory_aligned_buffer();
8213 test_source_resolver();
8214 test_MFCreateAsyncResult();
8215 test_allocate_queue();
8216 test_MFLockSharedWorkQueue();
8217 test_MFCopyImage();
8218 test_MFCreateCollection();
8219 test_MFHeapAlloc();
8220 test_scheduled_items();
8221 test_serial_queue();
8222 test_periodic_callback();
8223 test_event_queue();
8224 test_presentation_descriptor();
8225 test_system_time_source();
8226 test_MFInvokeCallback();
8227 test_stream_descriptor();
8228 test_MFCalculateImageSize();
8229 test_MFGetPlaneSize();
8230 test_MFCompareFullToPartialMediaType();
8231 test_attributes_serialization();
8232 test_wrapped_media_type();
8233 test_MFCreateWaveFormatExFromMFMediaType();
8234 test_async_create_file();
8235 test_local_handlers();
8236 test_create_property_store();
8237 test_dxgi_device_manager();
8238 test_MFCreateTransformActivate();
8239 test_MFTRegisterLocal();
8240 test_queue_com();
8241 test_MFGetStrideForBitmapInfoHeader();
8242 test_MFCreate2DMediaBuffer();
8243 test_MFCreateMediaBufferFromMediaType();
8244 test_MFInitMediaTypeFromWaveFormatEx();
8245 test_MFCreateMFVideoFormatFromMFMediaType();
8246 test_MFCreateDXSurfaceBuffer();
8247 test_MFCreateTrackedSample();
8248 test_MFFrameRateToAverageTimePerFrame();
8249 test_MFAverageTimePerFrameToFrameRate();
8250 test_MFMapDXGIFormatToDX9Format();
8251 test_d3d11_surface_buffer();
8252 test_d3d12_surface_buffer();
8253 test_sample_allocator_sysmem();
8254 test_sample_allocator_d3d9();
8255 test_sample_allocator_d3d11();
8256 test_sample_allocator_d3d12();
8257 test_MFMapDX9FormatToDXGIFormat();
8258 test_MFllMulDiv();
8259 test_shared_dxgi_device_manager();
8260 test_MFInitVideoFormat_RGB();
8262 CoUninitialize();