mfplat: Allow NULL size pointer in IMFAttributes::GetAllocatedBlob().
[wine.git] / dlls / mfplat / tests / mfplat.c
blob3f7ab161b5927e36cd3b6d88262208d90fdd9868
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;
1976 if(!pMFCreateMFByteStreamOnStream)
1978 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1979 return;
1982 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1983 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1985 caps = 0xffff0000;
1986 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1987 ok(hr == S_OK, "Failed to write, hr %#lx.\n", hr);
1989 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1990 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1992 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1993 (void **)&unknown);
1994 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
1995 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1996 ref = IUnknown_Release(unknown);
1997 ok(ref == 1, "got %lu\n", ref);
1999 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
2000 (void **)&bytestream2);
2001 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2002 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2003 ref = IMFByteStream_Release(bytestream2);
2004 ok(ref == 1, "got %lu\n", ref);
2006 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2007 (void **)&attributes);
2008 ok(hr == S_OK ||
2009 /* w7pro64 */
2010 broken(hr == E_NOINTERFACE), "Unexpected hr %#lx.\n", hr);
2012 if (hr != S_OK)
2014 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
2015 IStream_Release(stream);
2016 IMFByteStream_Release(bytestream);
2017 return;
2020 ok(attributes != NULL, "got NULL\n");
2021 hr = IMFAttributes_GetCount(attributes, &count);
2022 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2023 ok(count == 0, "Unexpected attributes count %u.\n", count);
2025 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
2026 (void **)&unknown);
2027 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2028 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
2029 ref = IUnknown_Release(unknown);
2030 ok(ref == 2, "got %lu\n", ref);
2032 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
2033 (void **)&bytestream2);
2034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2035 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
2036 ref = IMFByteStream_Release(bytestream2);
2037 ok(ref == 2, "got %lu\n", ref);
2039 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2040 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2041 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2042 check_interface(bytestream, &IID_IMFGetService, FALSE);
2044 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2045 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2046 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2048 hr = IMFByteStream_Close(bytestream);
2049 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2051 hr = IMFByteStream_Close(bytestream);
2052 ok(hr == S_OK, "Failed to close, hr %#lx.\n", hr);
2054 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2055 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2056 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2058 caps = 0;
2059 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
2060 ok(hr == S_OK, "Failed to read from stream, hr %#lx.\n", hr);
2061 ok(caps == 0xffff0000, "Unexpected content.\n");
2063 IMFAttributes_Release(attributes);
2064 IMFByteStream_Release(bytestream);
2065 IStream_Release(stream);
2068 static void test_file_stream(void)
2070 static const WCHAR newfilename[] = L"new.mp4";
2071 IMFByteStream *bytestream, *bytestream2;
2072 QWORD bytestream_length, position;
2073 IMFAttributes *attributes = NULL;
2074 MF_ATTRIBUTE_TYPE item_type;
2075 WCHAR pathW[MAX_PATH];
2076 WCHAR *filename;
2077 HRESULT hr;
2078 WCHAR *str;
2079 DWORD caps;
2080 UINT count;
2081 BOOL eos;
2083 filename = load_resource(L"test.mp4");
2085 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2086 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2088 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2089 MF_FILEFLAGS_NONE, filename, &bytestream);
2090 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2092 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
2093 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
2094 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
2095 check_interface(bytestream, &IID_IMFGetService, TRUE);
2097 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
2098 ok(hr == S_OK, "Failed to get stream capabilities, hr %#lx.\n", hr);
2099 if (is_win8_plus)
2101 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
2102 "Unexpected caps %#lx.\n", caps);
2104 else
2105 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#lx.\n", caps);
2107 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
2108 (void **)&attributes);
2109 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2110 ok(attributes != NULL, "got NULL\n");
2112 hr = IMFAttributes_GetCount(attributes, &count);
2113 ok(hr == S_OK, "Failed to get attributes count, hr %#lx.\n", hr);
2114 ok(count == 2, "Unexpected attributes count %u.\n", count);
2116 /* Original file name. */
2117 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
2118 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
2119 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
2120 CoTaskMemFree(str);
2122 /* Modification time. */
2123 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
2124 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
2125 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
2127 IMFAttributes_Release(attributes);
2129 /* Length. */
2130 hr = IMFByteStream_GetLength(bytestream, NULL);
2131 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2133 bytestream_length = 0;
2134 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
2135 ok(hr == S_OK, "Failed to get bytestream length, hr %#lx.\n", hr);
2136 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
2138 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
2139 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2141 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
2142 ok(hr == S_OK, "Failed query end of stream, hr %#lx.\n", hr);
2143 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
2145 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
2146 ok(hr == S_OK, "Failed to set bytestream position, hr %#lx.\n", hr);
2148 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
2149 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2151 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
2152 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2153 ok(position == 2 * bytestream_length, "Unexpected position.\n");
2155 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2156 MF_FILEFLAGS_NONE, filename, &bytestream2);
2157 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2158 IMFByteStream_Release(bytestream2);
2160 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2161 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2163 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
2164 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2166 IMFByteStream_Release(bytestream);
2168 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2169 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2170 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
2172 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2173 MF_FILEFLAGS_NONE, filename, &bytestream);
2174 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "Unexpected hr %#lx.\n", hr);
2176 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
2177 MF_FILEFLAGS_NONE, newfilename, &bytestream);
2178 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2180 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2181 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2183 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
2184 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2186 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2187 newfilename, &bytestream2);
2188 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2190 IMFByteStream_Release(bytestream);
2192 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
2193 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
2194 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2196 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
2197 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
2198 newfilename, &bytestream2);
2199 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#lx.\n", hr);
2201 IMFByteStream_Release(bytestream);
2203 /* Explicit file: scheme */
2204 lstrcpyW(pathW, fileschemeW);
2205 lstrcatW(pathW, filename);
2206 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2207 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2209 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream);
2210 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2211 ok(DeleteFileW(filename), "failed to delete file\n");
2212 IMFByteStream_Release(bytestream);
2214 hr = MFShutdown();
2215 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2217 DeleteFileW(newfilename);
2220 static void test_system_memory_buffer(void)
2222 IMFMediaBuffer *buffer;
2223 HRESULT hr;
2224 DWORD length, max;
2225 BYTE *data, *data2;
2227 hr = MFCreateMemoryBuffer(1024, NULL);
2228 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2230 hr = MFCreateMemoryBuffer(0, &buffer);
2231 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2232 if(buffer)
2234 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2235 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2236 ok(length == 0, "got %lu\n", length);
2238 IMFMediaBuffer_Release(buffer);
2241 hr = MFCreateMemoryBuffer(1024, &buffer);
2242 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2244 check_interface(buffer, &IID_IMFGetService, FALSE);
2246 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2247 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2249 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2250 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2251 ok(length == 1024, "got %lu\n", length);
2253 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2254 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2256 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2257 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2259 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2260 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2262 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2264 ok(length == 10, "got %lu\n", length);
2266 length = 0;
2267 max = 0;
2268 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2269 ok(hr == E_INVALIDARG || hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2270 ok(length == 0, "got %lu\n", length);
2271 ok(max == 0, "got %lu\n", length);
2273 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2275 ok(length == 10, "got %lu\n", length);
2276 ok(max == 1024, "got %lu\n", max);
2278 /* Attempt to lock the buffer twice */
2279 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2281 ok(data == data2, "Unexpected hr %#lx.\n", hr);
2283 hr = IMFMediaBuffer_Unlock(buffer);
2284 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2286 hr = IMFMediaBuffer_Unlock(buffer);
2287 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2289 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2290 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2292 hr = IMFMediaBuffer_Unlock(buffer);
2293 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2295 /* Extra Unlock */
2296 hr = IMFMediaBuffer_Unlock(buffer);
2297 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2299 IMFMediaBuffer_Release(buffer);
2302 static void test_system_memory_aligned_buffer(void)
2304 static const DWORD alignments[] =
2306 MF_16_BYTE_ALIGNMENT,
2307 MF_32_BYTE_ALIGNMENT,
2308 MF_64_BYTE_ALIGNMENT,
2309 MF_128_BYTE_ALIGNMENT,
2310 MF_256_BYTE_ALIGNMENT,
2311 MF_512_BYTE_ALIGNMENT,
2313 IMFMediaBuffer *buffer;
2314 DWORD length, max;
2315 unsigned int i;
2316 BYTE *data;
2317 HRESULT hr;
2319 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2320 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2322 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2323 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2325 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2326 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2327 ok(length == 0, "Unexpected current length %lu.\n", length);
2329 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2330 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2331 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2332 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2333 ok(length == 1, "Unexpected current length %lu.\n", length);
2335 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2336 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2337 ok(length == 201, "Unexpected max length %lu.\n", length);
2339 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2340 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2341 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2342 ok(hr == S_OK, "Failed to get max length, hr %#lx.\n", hr);
2343 ok(length == 201, "Unexpected max length %lu.\n", length);
2344 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2345 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2347 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2348 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2349 ok(max == 201 && length == 10, "Unexpected length.\n");
2350 hr = IMFMediaBuffer_Unlock(buffer);
2351 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2353 IMFMediaBuffer_Release(buffer);
2355 for (i = 0; i < ARRAY_SIZE(alignments); ++i)
2357 hr = MFCreateAlignedMemoryBuffer(200, alignments[i], &buffer);
2358 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2360 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2361 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
2362 ok(max == 200 && !length, "Unexpected length.\n");
2363 ok(!((uintptr_t)data & alignments[i]), "Data at %p is misaligned.\n", data);
2364 hr = IMFMediaBuffer_Unlock(buffer);
2365 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2367 IMFMediaBuffer_Release(buffer);
2370 hr = MFCreateAlignedMemoryBuffer(200, 0, &buffer);
2371 ok(hr == S_OK, "Failed to create memory buffer, hr %#lx.\n", hr);
2372 IMFMediaBuffer_Release(buffer);
2375 static void test_sample(void)
2377 static const DWORD test_pattern = 0x22222222;
2378 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2379 DWORD count, flags, length;
2380 IMFAttributes *attributes;
2381 IMFSample *sample;
2382 LONGLONG time;
2383 HRESULT hr;
2384 BYTE *data;
2386 hr = MFCreateSample( &sample );
2387 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2389 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2390 ok(hr == S_OK, "Failed to get attributes interface, hr %#lx.\n", hr);
2392 CHECK_ATTR_COUNT(attributes, 0);
2394 hr = IMFSample_GetBufferCount(sample, NULL);
2395 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2397 hr = IMFSample_GetBufferCount(sample, &count);
2398 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2399 ok(count == 0, "got %ld\n", count);
2401 hr = IMFSample_GetSampleFlags(sample, &flags);
2402 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2403 ok(!flags, "Unexpected flags %#lx.\n", flags);
2405 hr = IMFSample_SetSampleFlags(sample, 0x123);
2406 ok(hr == S_OK, "Failed to set sample flags, hr %#lx.\n", hr);
2407 hr = IMFSample_GetSampleFlags(sample, &flags);
2408 ok(hr == S_OK, "Failed to get sample flags, hr %#lx.\n", hr);
2409 ok(flags == 0x123, "Unexpected flags %#lx.\n", flags);
2411 hr = IMFSample_GetSampleTime(sample, &time);
2412 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#lx.\n", hr);
2414 hr = IMFSample_GetSampleDuration(sample, &time);
2415 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#lx.\n", hr);
2417 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2418 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2420 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2421 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
2423 hr = IMFSample_RemoveAllBuffers(sample);
2424 ok(hr == S_OK, "Failed to remove all, hr %#lx.\n", hr);
2426 hr = IMFSample_GetTotalLength(sample, &length);
2427 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2428 ok(!length, "Unexpected total length %lu.\n", length);
2430 hr = MFCreateMemoryBuffer(16, &buffer);
2431 ok(hr == S_OK, "Failed to create buffer, hr %#lx.\n", hr);
2433 hr = IMFSample_AddBuffer(sample, buffer);
2434 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2436 hr = IMFSample_AddBuffer(sample, buffer);
2437 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2439 hr = IMFSample_GetBufferCount(sample, &count);
2440 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2441 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2443 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2444 ok(hr == S_OK, "Failed to get buffer, hr %#lx.\n", hr);
2445 ok(buffer2 == buffer, "Unexpected object.\n");
2446 IMFMediaBuffer_Release(buffer2);
2448 hr = IMFSample_GetTotalLength(sample, &length);
2449 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2450 ok(!length, "Unexpected total length %lu.\n", length);
2452 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2453 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2455 hr = IMFSample_GetTotalLength(sample, &length);
2456 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2457 ok(length == 4, "Unexpected total length %lu.\n", length);
2459 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2460 ok(hr == S_OK, "Failed to remove buffer, hr %#lx.\n", hr);
2462 hr = IMFSample_GetTotalLength(sample, &length);
2463 ok(hr == S_OK, "Failed to get total length, hr %#lx.\n", hr);
2464 ok(length == 2, "Unexpected total length %lu.\n", length);
2466 IMFMediaBuffer_Release(buffer);
2468 /* Duration */
2469 hr = IMFSample_SetSampleDuration(sample, 10);
2470 ok(hr == S_OK, "Failed to set duration, hr %#lx.\n", hr);
2471 CHECK_ATTR_COUNT(attributes, 0);
2472 hr = IMFSample_GetSampleDuration(sample, &time);
2473 ok(hr == S_OK, "Failed to get sample duration, hr %#lx.\n", hr);
2474 ok(time == 10, "Unexpected duration.\n");
2476 /* Timestamp */
2477 hr = IMFSample_SetSampleTime(sample, 1);
2478 ok(hr == S_OK, "Failed to set timestamp, hr %#lx.\n", hr);
2479 CHECK_ATTR_COUNT(attributes, 0);
2480 hr = IMFSample_GetSampleTime(sample, &time);
2481 ok(hr == S_OK, "Failed to get sample time, hr %#lx.\n", hr);
2482 ok(time == 1, "Unexpected timestamp.\n");
2484 IMFAttributes_Release(attributes);
2485 IMFSample_Release(sample);
2487 /* CopyToBuffer() */
2488 hr = MFCreateSample(&sample);
2489 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2491 hr = MFCreateMemoryBuffer(16, &buffer2);
2492 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2494 /* Sample with no buffers. */
2495 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2496 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2497 hr = IMFSample_CopyToBuffer(sample, buffer2);
2498 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2499 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2500 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
2501 ok(!length, "Unexpected length %lu.\n", length);
2503 /* Single buffer, larger destination. */
2504 hr = MFCreateMemoryBuffer(8, &buffer);
2505 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2507 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2508 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2509 *(DWORD *)data = 0x11111111;
2510 hr = IMFMediaBuffer_Unlock(buffer);
2511 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
2512 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2513 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2515 hr = IMFSample_AddBuffer(sample, buffer);
2516 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2518 /* Existing content is overwritten. */
2519 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2520 ok(hr == S_OK, "Failed to set length, hr %#lx.\n", hr);
2522 hr = IMFSample_CopyToBuffer(sample, buffer2);
2523 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2525 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2526 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2527 ok(length == 4, "Unexpected buffer length %lu.\n", length);
2529 /* Multiple buffers, matching total size. */
2530 hr = IMFSample_AddBuffer(sample, buffer);
2531 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2533 hr = IMFSample_GetBufferCount(sample, &count);
2534 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2535 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2537 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2538 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
2540 hr = IMFSample_CopyToBuffer(sample, buffer2);
2541 ok(hr == S_OK, "Failed to copy to buffer, hr %#lx.\n", hr);
2543 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2544 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2545 ok(length == 16, "Unexpected buffer length %lu.\n", length);
2547 hr = IMFSample_AddBuffer(sample, buffer);
2548 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2550 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2551 ok(hr == S_OK, "Failed to set buffer length, hr %#lx.\n", hr);
2553 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2554 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2555 *(DWORD *)data = test_pattern;
2556 hr = IMFMediaBuffer_Unlock(buffer2);
2557 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2559 hr = IMFSample_CopyToBuffer(sample, buffer2);
2560 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
2562 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2563 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
2564 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#lx\n", *(DWORD *)data);
2565 hr = IMFMediaBuffer_Unlock(buffer2);
2566 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
2568 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2569 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
2570 ok(!length, "Unexpected buffer length %lu.\n", length);
2572 IMFMediaBuffer_Release(buffer2);
2573 IMFSample_Release(sample);
2575 /* ConvertToContiguousBuffer() */
2576 hr = MFCreateSample(&sample);
2577 ok(hr == S_OK, "Failed to create a sample, hr %#lx.\n", hr);
2579 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2580 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
2582 hr = MFCreateMemoryBuffer(16, &buffer);
2583 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2585 hr = IMFSample_AddBuffer(sample, buffer);
2586 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2588 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2589 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2590 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2591 IMFMediaBuffer_Release(buffer2);
2593 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2594 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2596 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2597 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2598 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2599 IMFMediaBuffer_Release(buffer2);
2601 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2604 hr = MFCreateMemoryBuffer(16, &buffer2);
2605 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
2607 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2608 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2610 hr = IMFSample_AddBuffer(sample, buffer2);
2611 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2612 IMFMediaBuffer_Release(buffer2);
2614 hr = IMFSample_GetBufferCount(sample, &count);
2615 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2616 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2618 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2619 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2621 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2622 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2623 ok(length == 7, "Unexpected length %lu.\n", length);
2625 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2626 ok(hr == S_OK, "Failed to get maximum length, hr %#lx.\n", hr);
2627 ok(length == 7, "Unexpected length %lu.\n", length);
2629 IMFMediaBuffer_Release(buffer3);
2631 hr = IMFSample_GetBufferCount(sample, &count);
2632 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2633 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2635 hr = IMFSample_AddBuffer(sample, buffer);
2636 ok(hr == S_OK, "Failed to add buffer, hr %#lx.\n", hr);
2638 hr = IMFSample_GetBufferCount(sample, &count);
2639 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2640 ok(count == 2, "Unexpected buffer count %lu.\n", count);
2642 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2643 ok(hr == S_OK, "Failed to convert, hr %#lx.\n", hr);
2645 hr = IMFSample_GetBufferCount(sample, &count);
2646 ok(hr == S_OK, "Failed to get buffer count, hr %#lx.\n", hr);
2647 ok(count == 1, "Unexpected buffer count %lu.\n", count);
2649 IMFMediaBuffer_Release(buffer);
2651 IMFSample_Release(sample);
2654 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2656 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2657 IMFMediaEventQueue *queue;
2658 IUnknown *state, *obj;
2659 HRESULT hr;
2661 ok(result != NULL, "Unexpected result object.\n");
2663 state = IMFAsyncResult_GetStateNoAddRef(result);
2664 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2666 IMFMediaEvent *event = NULL, *event2;
2668 if (is_win8_plus)
2670 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2671 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2673 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2674 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#lx.\n", hr);
2676 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2677 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#lx.\n", hr);
2679 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2680 ok(hr == E_FAIL, "Unexpected result, hr %#lx.\n", hr);
2682 if (event)
2683 IMFMediaEvent_Release(event);
2686 hr = IMFAsyncResult_GetObject(result, &obj);
2687 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2689 IMFMediaEventQueue_Release(queue);
2691 SetEvent(callback->event);
2694 return E_NOTIMPL;
2697 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2699 testcallback_QueryInterface,
2700 testcallback_AddRef,
2701 testcallback_Release,
2702 testcallback_GetParameters,
2703 testcallback_Invoke,
2706 static void test_MFCreateAsyncResult(void)
2708 IMFAsyncResult *result, *result2;
2709 struct test_callback *callback;
2710 IUnknown *state, *object;
2711 MFASYNCRESULT *data;
2712 ULONG refcount;
2713 HANDLE event;
2714 DWORD flags;
2715 HRESULT hr;
2716 BOOL ret;
2718 callback = create_test_callback(NULL);
2720 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2721 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2723 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2724 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2726 data = (MFASYNCRESULT *)result;
2727 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2728 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2729 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2730 ok(data->hEvent == NULL, "Unexpected event.\n");
2732 hr = IMFAsyncResult_GetState(result, NULL);
2733 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2735 state = (void *)0xdeadbeef;
2736 hr = IMFAsyncResult_GetState(result, &state);
2737 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2738 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2740 hr = IMFAsyncResult_GetStatus(result);
2741 ok(hr == S_OK, "Unexpected status %#lx.\n", hr);
2743 data->hrStatusResult = 123;
2744 hr = IMFAsyncResult_GetStatus(result);
2745 ok(hr == 123, "Unexpected status %#lx.\n", hr);
2747 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2748 ok(hr == S_OK, "Failed to set status, hr %#lx.\n", hr);
2749 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#lx.\n", hr);
2751 hr = IMFAsyncResult_GetObject(result, NULL);
2752 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2754 object = (void *)0xdeadbeef;
2755 hr = IMFAsyncResult_GetObject(result, &object);
2756 ok(hr == E_POINTER, "Failed to get object, hr %#lx.\n", hr);
2757 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2759 state = IMFAsyncResult_GetStateNoAddRef(result);
2760 ok(state == NULL, "Unexpected state.\n");
2762 /* Object. */
2763 hr = MFCreateAsyncResult((IUnknown *)result, &callback->IMFAsyncCallback_iface, NULL, &result2);
2764 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2766 data = (MFASYNCRESULT *)result2;
2767 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2768 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2769 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2770 ok(data->hEvent == NULL, "Unexpected event.\n");
2772 object = NULL;
2773 hr = IMFAsyncResult_GetObject(result2, &object);
2774 ok(hr == S_OK, "Failed to get object, hr %#lx.\n", hr);
2775 ok(object == (IUnknown *)result, "Unexpected object.\n");
2776 IUnknown_Release(object);
2778 IMFAsyncResult_Release(result2);
2780 /* State object. */
2781 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2782 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2784 data = (MFASYNCRESULT *)result2;
2785 ok(data->pCallback == &callback->IMFAsyncCallback_iface, "Unexpected callback value.\n");
2786 ok(data->hrStatusResult == S_OK, "Unexpected status %#lx.\n", data->hrStatusResult);
2787 ok(data->dwBytesTransferred == 0, "Unexpected byte length %lu.\n", data->dwBytesTransferred);
2788 ok(data->hEvent == NULL, "Unexpected event.\n");
2790 state = NULL;
2791 hr = IMFAsyncResult_GetState(result2, &state);
2792 ok(hr == S_OK, "Failed to get state object, hr %#lx.\n", hr);
2793 ok(state == (IUnknown *)result, "Unexpected state.\n");
2794 IUnknown_Release(state);
2796 state = IMFAsyncResult_GetStateNoAddRef(result2);
2797 ok(state == (IUnknown *)result, "Unexpected state.\n");
2799 refcount = IMFAsyncResult_Release(result2);
2800 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2801 refcount = IMFAsyncResult_Release(result);
2802 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2804 /* Event handle is closed on release. */
2805 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2806 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2808 data = (MFASYNCRESULT *)result;
2809 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2810 ok(data->hEvent != NULL, "Failed to create event.\n");
2811 ret = GetHandleInformation(event, &flags);
2812 ok(ret, "Failed to get handle info.\n");
2814 refcount = IMFAsyncResult_Release(result);
2815 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2816 ret = GetHandleInformation(event, &flags);
2817 ok(!ret, "Expected handle to be closed.\n");
2819 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
2820 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
2822 data = (MFASYNCRESULT *)result;
2823 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2824 ok(data->hEvent != NULL, "Failed to create event.\n");
2825 ret = GetHandleInformation(event, &flags);
2826 ok(ret, "Failed to get handle info.\n");
2828 refcount = IMFAsyncResult_Release(result);
2829 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
2830 ret = GetHandleInformation(event, &flags);
2831 ok(!ret, "Expected handle to be closed.\n");
2833 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
2836 static void test_startup(void)
2838 DWORD queue;
2839 HRESULT hr;
2841 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2842 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#lx.\n", hr);
2844 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2845 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2847 hr = MFAllocateWorkQueue(&queue);
2848 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2849 hr = MFUnlockWorkQueue(queue);
2850 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2852 hr = MFShutdown();
2853 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2855 hr = MFAllocateWorkQueue(&queue);
2856 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2858 /* Already shut down, has no effect. */
2859 hr = MFShutdown();
2860 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2862 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2863 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2865 hr = MFAllocateWorkQueue(&queue);
2866 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2867 hr = MFUnlockWorkQueue(queue);
2868 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2870 hr = MFShutdown();
2871 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2873 /* Platform lock. */
2874 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2875 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2877 hr = MFAllocateWorkQueue(&queue);
2878 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2879 hr = MFUnlockWorkQueue(queue);
2880 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2882 /* Unlocking implies shutdown. */
2883 hr = MFUnlockPlatform();
2884 ok(hr == S_OK, "Failed to unlock, %#lx.\n", hr);
2886 hr = MFAllocateWorkQueue(&queue);
2887 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
2889 hr = MFLockPlatform();
2890 ok(hr == S_OK, "Failed to lock, %#lx.\n", hr);
2892 hr = MFAllocateWorkQueue(&queue);
2893 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2894 hr = MFUnlockWorkQueue(queue);
2895 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2897 hr = MFShutdown();
2898 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2901 static void test_allocate_queue(void)
2903 DWORD queue, queue2;
2904 HRESULT hr;
2906 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2907 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
2909 hr = MFAllocateWorkQueue(&queue);
2910 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2911 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2913 hr = MFUnlockWorkQueue(queue);
2914 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2916 hr = MFUnlockWorkQueue(queue);
2917 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
2919 hr = MFAllocateWorkQueue(&queue2);
2920 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
2921 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2923 hr = MFUnlockWorkQueue(queue2);
2924 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
2926 /* Unlock in system queue range. */
2927 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2928 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2930 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2931 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2933 hr = MFUnlockWorkQueue(0x20);
2934 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
2936 hr = MFShutdown();
2937 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
2940 static void test_MFCopyImage(void)
2942 BYTE dest[16], src[16];
2943 HRESULT hr;
2945 if (!pMFCopyImage)
2947 win_skip("MFCopyImage() is not available.\n");
2948 return;
2951 memset(dest, 0xaa, sizeof(dest));
2952 memset(src, 0x11, sizeof(src));
2954 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2955 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
2956 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2958 memset(dest, 0xaa, sizeof(dest));
2959 memset(src, 0x11, sizeof(src));
2961 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2962 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
2963 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2965 memset(dest, 0xaa, sizeof(dest));
2966 memset(src, 0x11, sizeof(src));
2968 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2969 ok(hr == S_OK, "Failed to copy image %#lx.\n", hr);
2970 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2973 static void test_MFCreateCollection(void)
2975 IMFCollection *collection;
2976 IUnknown *element;
2977 DWORD count;
2978 HRESULT hr;
2980 hr = MFCreateCollection(NULL);
2981 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2983 hr = MFCreateCollection(&collection);
2984 ok(hr == S_OK, "Failed to create collection, hr %#lx.\n", hr);
2986 hr = IMFCollection_GetElementCount(collection, NULL);
2987 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2989 count = 1;
2990 hr = IMFCollection_GetElementCount(collection, &count);
2991 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
2992 ok(count == 0, "Unexpected count %lu.\n", count);
2994 hr = IMFCollection_GetElement(collection, 0, NULL);
2995 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
2997 element = (void *)0xdeadbeef;
2998 hr = IMFCollection_GetElement(collection, 0, &element);
2999 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3000 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3002 hr = IMFCollection_RemoveElement(collection, 0, NULL);
3003 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3005 element = (void *)0xdeadbeef;
3006 hr = IMFCollection_RemoveElement(collection, 0, &element);
3007 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#lx.\n", hr);
3008 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
3010 hr = IMFCollection_RemoveAllElements(collection);
3011 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3013 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
3014 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3016 count = 0;
3017 hr = IMFCollection_GetElementCount(collection, &count);
3018 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3019 ok(count == 1, "Unexpected count %lu.\n", count);
3021 hr = IMFCollection_AddElement(collection, NULL);
3022 ok(hr == S_OK, "Failed to add element, hr %#lx.\n", hr);
3024 count = 0;
3025 hr = IMFCollection_GetElementCount(collection, &count);
3026 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3027 ok(count == 2, "Unexpected count %lu.\n", count);
3029 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
3030 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3032 count = 0;
3033 hr = IMFCollection_GetElementCount(collection, &count);
3034 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3035 ok(count == 11, "Unexpected count %lu.\n", count);
3037 hr = IMFCollection_GetElement(collection, 0, &element);
3038 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3039 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3040 IUnknown_Release(element);
3042 hr = IMFCollection_GetElement(collection, 1, &element);
3043 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3044 ok(!element, "Unexpected element.\n");
3046 hr = IMFCollection_GetElement(collection, 2, &element);
3047 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3048 ok(!element, "Unexpected element.\n");
3050 hr = IMFCollection_GetElement(collection, 10, &element);
3051 ok(hr == S_OK, "Failed to get element, hr %#lx.\n", hr);
3052 ok(element == (IUnknown *)collection, "Unexpected element.\n");
3053 IUnknown_Release(element);
3055 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3056 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3058 hr = IMFCollection_GetElement(collection, 0, &element);
3059 ok(hr == E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
3061 hr = IMFCollection_RemoveAllElements(collection);
3062 ok(hr == S_OK, "Failed to clear, hr %#lx.\n", hr);
3064 count = 1;
3065 hr = IMFCollection_GetElementCount(collection, &count);
3066 ok(hr == S_OK, "Failed to get element count, hr %#lx.\n", hr);
3067 ok(count == 0, "Unexpected count %lu.\n", count);
3069 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
3070 ok(hr == S_OK, "Failed to insert element, hr %#lx.\n", hr);
3072 IMFCollection_Release(collection);
3075 static void test_MFHeapAlloc(void)
3077 void *res;
3079 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
3080 ok(res != NULL, "MFHeapAlloc failed.\n");
3082 MFHeapFree(res);
3085 static void test_scheduled_items(void)
3087 struct test_callback *callback;
3088 IMFAsyncResult *result;
3089 MFWORKITEM_KEY key, key2;
3090 HRESULT hr;
3092 callback = create_test_callback(NULL);
3094 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3095 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3097 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3098 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3100 hr = MFCancelWorkItem(key);
3101 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3103 hr = MFCancelWorkItem(key);
3104 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#lx.\n", hr);
3106 if (!pMFPutWaitingWorkItem)
3108 win_skip("Waiting items are not supported.\n");
3109 return;
3112 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3113 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3115 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
3116 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3118 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
3119 ok(hr == S_OK, "Failed to add waiting item, hr %#lx.\n", hr);
3121 hr = MFCancelWorkItem(key);
3122 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3124 hr = MFCancelWorkItem(key2);
3125 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3127 IMFAsyncResult_Release(result);
3129 hr = MFScheduleWorkItem(&callback->IMFAsyncCallback_iface, NULL, -5000, &key);
3130 ok(hr == S_OK, "Failed to schedule item, hr %#lx.\n", hr);
3132 hr = MFCancelWorkItem(key);
3133 ok(hr == S_OK, "Failed to cancel item, hr %#lx.\n", hr);
3135 hr = MFShutdown();
3136 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3138 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3141 static void test_serial_queue(void)
3143 static const DWORD queue_ids[] =
3145 MFASYNC_CALLBACK_QUEUE_STANDARD,
3146 MFASYNC_CALLBACK_QUEUE_RT,
3147 MFASYNC_CALLBACK_QUEUE_IO,
3148 MFASYNC_CALLBACK_QUEUE_TIMER,
3149 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
3150 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
3152 DWORD queue, serial_queue;
3153 unsigned int i;
3154 HRESULT hr;
3156 if (!pMFAllocateSerialWorkQueue)
3158 win_skip("Serial queues are not supported.\n");
3159 return;
3162 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3163 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3165 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
3167 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
3168 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
3170 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
3171 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
3172 "%u: failed to allocate a queue, hr %#lx.\n", i, hr);
3174 if (SUCCEEDED(hr))
3176 hr = MFUnlockWorkQueue(serial_queue);
3177 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#lx.\n", i, hr);
3181 /* Chain them together. */
3182 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
3183 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3185 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
3186 ok(hr == S_OK, "Failed to allocate a queue, hr %#lx.\n", hr);
3188 hr = MFUnlockWorkQueue(serial_queue);
3189 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3191 hr = MFUnlockWorkQueue(queue);
3192 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
3194 hr = MFShutdown();
3195 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3198 static LONG periodic_counter;
3199 static void CALLBACK periodic_callback(IUnknown *context)
3201 InterlockedIncrement(&periodic_counter);
3204 static void test_periodic_callback(void)
3206 DWORD period, key;
3207 HRESULT hr;
3209 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3210 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3212 period = 0;
3213 hr = MFGetTimerPeriodicity(&period);
3214 ok(hr == S_OK, "Failed to get timer perdiod, hr %#lx.\n", hr);
3215 ok(period == 10, "Unexpected period %lu.\n", period);
3217 if (!pMFAddPeriodicCallback)
3219 win_skip("Periodic callbacks are not supported.\n");
3220 hr = MFShutdown();
3221 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3222 return;
3225 ok(periodic_counter == 0, "Unexpected counter value %lu.\n", periodic_counter);
3227 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
3228 ok(hr == S_OK, "Failed to add periodic callback, hr %#lx.\n", hr);
3229 ok(key != 0, "Unexpected key %#lx.\n", key);
3231 Sleep(10 * period);
3233 hr = pMFRemovePeriodicCallback(key);
3234 ok(hr == S_OK, "Failed to remove callback, hr %#lx.\n", hr);
3236 ok(periodic_counter > 0, "Unexpected counter value %lu.\n", periodic_counter);
3238 hr = MFShutdown();
3239 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3242 static void test_event_queue(void)
3244 struct test_callback *callback, *callback2;
3245 IMFMediaEvent *event, *event2;
3246 IMFMediaEventQueue *queue;
3247 IMFAsyncResult *result;
3248 HRESULT hr;
3249 DWORD ret;
3251 callback = create_test_callback(NULL);
3252 callback2 = create_test_callback(NULL);
3254 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3255 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3257 hr = MFCreateEventQueue(&queue);
3258 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3260 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3261 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr);
3263 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3264 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3266 if (is_win8_plus)
3268 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3269 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3271 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3273 ok(event2 == event, "Unexpected event object.\n");
3274 IMFMediaEvent_Release(event2);
3276 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3277 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3279 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3280 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3281 IMFMediaEvent_Release(event2);
3284 /* Async case. */
3285 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3286 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3288 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3289 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3291 /* Same callback, same state. */
3292 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)queue);
3293 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3295 /* Same callback, different state. */
3296 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3297 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#lx.\n", hr);
3299 /* Different callback, same state. */
3300 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)queue);
3301 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3303 /* Different callback, different state. */
3304 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface);
3305 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#lx.\n", hr);
3307 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
3309 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3310 ok(hr == S_OK, "Failed to queue event, hr %#lx.\n", hr);
3312 ret = WaitForSingleObject(callback->event, 500);
3313 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#lx.\n", ret);
3315 CloseHandle(callback->event);
3317 IMFMediaEvent_Release(event);
3319 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3320 ok(hr == S_OK, "Failed to create result, hr %#lx.\n", hr);
3322 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3323 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
3325 /* Shutdown behavior. */
3326 hr = IMFMediaEventQueue_Shutdown(queue);
3327 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3329 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3330 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3332 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3333 ok(hr == S_OK, "Failed to create event object, hr %#lx.\n", hr);
3334 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3335 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3336 IMFMediaEvent_Release(event);
3338 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3339 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3341 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3342 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3344 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3345 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3347 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3348 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3350 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3351 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
3352 IMFAsyncResult_Release(result);
3354 /* Already shut down. */
3355 hr = IMFMediaEventQueue_Shutdown(queue);
3356 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3358 IMFMediaEventQueue_Release(queue);
3359 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3361 /* Release while subscribed. */
3362 callback = create_test_callback(NULL);
3364 hr = MFCreateEventQueue(&queue);
3365 ok(hr == S_OK, "Failed to create event queue, hr %#lx.\n", hr);
3367 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback->IMFAsyncCallback_iface, NULL);
3368 ok(hr == S_OK, "Failed to Begin*, hr %#lx.\n", hr);
3369 EXPECT_REF(&callback->IMFAsyncCallback_iface, 2);
3371 IMFMediaEventQueue_Release(queue);
3372 ret = get_refcount(&callback->IMFAsyncCallback_iface);
3373 ok(ret == 1 || broken(ret == 2) /* Vista */,
3374 "Unexpected refcount %ld, expected 1.\n", ret);
3375 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3377 hr = MFShutdown();
3378 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3381 static void test_presentation_descriptor(void)
3383 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3384 IMFPresentationDescriptor *pd, *pd2;
3385 IMFMediaType *media_type;
3386 unsigned int i;
3387 BOOL selected;
3388 UINT64 value;
3389 DWORD count;
3390 HRESULT hr;
3392 hr = MFCreateMediaType(&media_type);
3393 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3395 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3397 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3398 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3401 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3402 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#lx.\n", hr);
3404 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3405 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %lu.\n", count);
3407 for (i = 0; i < count; ++i)
3409 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3410 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3411 ok(!selected, "Unexpected selected state.\n");
3412 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3413 IMFStreamDescriptor_Release(stream_desc2);
3416 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3417 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3419 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3420 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3422 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3423 ok(hr == S_OK, "Failed to select a stream, hr %#lx.\n", hr);
3425 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3426 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3427 ok(!!selected, "Unexpected selected state.\n");
3428 IMFStreamDescriptor_Release(stream_desc2);
3430 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3431 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
3433 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3434 ok(hr == S_OK, "Failed to clone, hr %#lx.\n", hr);
3436 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3437 ok(hr == S_OK, "Failed to get stream descriptor, hr %#lx.\n", hr);
3438 ok(!!selected, "Unexpected selected state.\n");
3439 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3440 IMFStreamDescriptor_Release(stream_desc2);
3442 value = 0;
3443 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3444 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
3445 ok(value == 1, "Unexpected attribute value.\n");
3447 IMFPresentationDescriptor_Release(pd2);
3448 IMFPresentationDescriptor_Release(pd);
3450 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3452 IMFStreamDescriptor_Release(stream_desc[i]);
3455 /* Partially initialized array. */
3456 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3457 ok(hr == S_OK, "Failed to create descriptor, hr %#lx.\n", hr);
3458 stream_desc[0] = NULL;
3460 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3461 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3463 IMFStreamDescriptor_Release(stream_desc[1]);
3464 IMFMediaType_Release(media_type);
3467 enum clock_action
3469 CLOCK_START,
3470 CLOCK_STOP,
3471 CLOCK_PAUSE,
3472 CLOCK_RESTART,
3475 static void test_system_time_source(void)
3477 static const struct clock_state_test
3479 enum clock_action action;
3480 MFCLOCK_STATE state;
3481 BOOL is_invalid;
3483 clock_state_change[] =
3485 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3486 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3487 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3488 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3489 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3490 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3491 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3492 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3493 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3494 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3495 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3496 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3497 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3498 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3499 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3500 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3501 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3503 IMFPresentationTimeSource *time_source, *time_source2;
3504 IMFClockStateSink *statesink;
3505 IMFClock *clock, *clock2;
3506 MFCLOCK_PROPERTIES props;
3507 MFCLOCK_STATE state;
3508 unsigned int i;
3509 MFTIME systime;
3510 LONGLONG time;
3511 DWORD value;
3512 HRESULT hr;
3514 hr = MFCreateSystemTimeSource(&time_source);
3515 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3517 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3518 ok(hr == S_OK, "Failed to get flags, hr %#lx.\n", hr);
3519 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3520 "Unexpected flags %#lx.\n", value);
3522 value = 1;
3523 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3525 ok(value == 0, "Unexpected value %lu.\n", value);
3527 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3528 ok(hr == S_OK, "Failed to get state, hr %#lx.\n", hr);
3529 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3531 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3532 ok(hr == S_OK, "Failed to get state sink, hr %#lx.\n", hr);
3534 /* State changes. */
3535 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3537 switch (clock_state_change[i].action)
3539 case CLOCK_STOP:
3540 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3541 break;
3542 case CLOCK_RESTART:
3543 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3544 break;
3545 case CLOCK_PAUSE:
3546 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3547 break;
3548 case CLOCK_START:
3549 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3550 break;
3551 default:
3554 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#lx.\n", i, hr);
3555 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3556 ok(hr == S_OK, "%u: failed to get state, hr %#lx.\n", i, hr);
3557 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3560 IMFClockStateSink_Release(statesink);
3562 /* Properties. */
3563 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3564 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
3566 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3567 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3569 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3570 wine_dbgstr_longlong(props.qwCorrelationRate));
3571 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3572 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3573 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3574 wine_dbgstr_longlong(props.qwClockFrequency));
3575 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3576 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3578 /* Underlying clock. */
3579 hr = MFCreateSystemTimeSource(&time_source2);
3580 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3581 EXPECT_REF(time_source2, 1);
3582 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3583 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3584 EXPECT_REF(time_source2, 1);
3585 EXPECT_REF(clock2, 2);
3587 EXPECT_REF(time_source, 1);
3588 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3589 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3590 EXPECT_REF(time_source, 1);
3591 EXPECT_REF(clock, 2);
3593 ok(clock != clock2, "Unexpected clock instance.\n");
3595 IMFPresentationTimeSource_Release(time_source2);
3596 IMFClock_Release(clock2);
3598 hr = IMFClock_GetClockCharacteristics(clock, &value);
3599 ok(hr == S_OK, "Failed to get clock flags, hr %#lx.\n", hr);
3600 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3601 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#lx.\n", value);
3603 hr = IMFClock_GetContinuityKey(clock, &value);
3604 ok(hr == S_OK, "Failed to get clock key, hr %#lx.\n", hr);
3605 ok(value == 0, "Unexpected key value %lu.\n", value);
3607 hr = IMFClock_GetState(clock, 0, &state);
3608 ok(hr == S_OK, "Failed to get clock state, hr %#lx.\n", hr);
3609 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3611 hr = IMFClock_GetProperties(clock, &props);
3612 ok(hr == S_OK, "Failed to get clock properties, hr %#lx.\n", hr);
3614 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3615 wine_dbgstr_longlong(props.qwCorrelationRate));
3616 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3617 ok(props.dwClockFlags == 0, "Unexpected flags %#lx.\n", props.dwClockFlags);
3618 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3619 wine_dbgstr_longlong(props.qwClockFrequency));
3620 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %lu.\n", props.dwClockTolerance);
3621 ok(props.dwClockJitter == 1, "Unexpected jitter %lu.\n", props.dwClockJitter);
3623 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3624 ok(hr == S_OK, "Failed to get clock time, hr %#lx.\n", hr);
3625 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3627 IMFClock_Release(clock);
3629 /* Test returned time regarding specified rate and offset. */
3630 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3631 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3633 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3634 ok(hr == S_OK, "Failed to get state %#lx.\n", hr);
3635 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3637 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3638 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3639 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3641 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3642 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3644 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3645 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3646 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3648 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3649 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3651 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3652 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3653 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3654 wine_dbgstr_longlong(systime));
3656 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3657 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3659 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3660 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3661 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3663 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3664 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3666 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3667 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3668 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3669 wine_dbgstr_longlong(systime));
3671 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3672 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3674 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3675 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3676 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3677 wine_dbgstr_longlong(systime));
3679 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3680 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3682 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3683 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3684 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3686 /* Increased rate. */
3687 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3688 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3690 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3691 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3693 hr = IMFClockStateSink_OnClockSetRate(statesink, 5, 2.0f);
3694 ok(hr == S_OK, "Failed to set rate, hr %#lx.\n", hr);
3696 hr = IMFClockStateSink_OnClockPause(statesink, 6);
3697 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3699 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3700 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3701 ok(time == 12 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3702 wine_dbgstr_longlong(systime));
3704 hr = IMFClockStateSink_OnClockRestart(statesink, 7);
3705 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3707 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3708 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3710 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3711 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3712 ok(time == 14 && !!systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3713 wine_dbgstr_longlong(systime));
3715 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3716 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3718 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3719 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3720 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3721 wine_dbgstr_longlong(2 * systime));
3723 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3724 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3726 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3727 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3728 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3729 wine_dbgstr_longlong(2 * systime));
3731 hr = IMFClockStateSink_OnClockPause(statesink, 2);
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 == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3737 wine_dbgstr_longlong(systime));
3739 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3740 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3742 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3743 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3744 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3745 wine_dbgstr_longlong(systime));
3747 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3748 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3750 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3751 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3752 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3753 wine_dbgstr_longlong(systime));
3755 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3756 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3758 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3759 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3760 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3762 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3763 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3765 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3766 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3767 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3768 wine_dbgstr_longlong(2 * systime));
3770 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3771 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3773 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3774 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3776 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3777 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3778 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3779 wine_dbgstr_longlong(2 * systime));
3781 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3782 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3784 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3785 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3786 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3787 wine_dbgstr_longlong(systime));
3789 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3790 ok(hr == S_OK, "Failed to restart source, hr %#lx.\n", hr);
3792 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3793 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3794 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3795 wine_dbgstr_longlong(systime));
3797 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3798 ok(hr == S_OK, "Failed to pause 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 == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3803 wine_dbgstr_longlong(systime));
3805 IMFClockStateSink_Release(statesink);
3806 IMFPresentationTimeSource_Release(time_source);
3808 /* PRESENTATION_CURRENT_POSITION */
3809 hr = MFCreateSystemTimeSource(&time_source);
3810 ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr);
3812 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3813 ok(hr == S_OK, "Failed to get sink interface, hr %#lx.\n", hr);
3815 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3816 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3817 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3818 wine_dbgstr_longlong(systime));
3820 /* INVALID -> RUNNING */
3821 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3822 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3824 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3825 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3826 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3827 wine_dbgstr_longlong(systime));
3829 /* RUNNING -> RUNNING */
3830 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3831 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3833 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3834 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3835 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3836 wine_dbgstr_longlong(systime));
3838 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3839 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3841 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3842 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3843 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3844 wine_dbgstr_longlong(systime));
3846 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3847 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3849 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3850 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3851 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3852 wine_dbgstr_longlong(systime));
3854 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3855 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3857 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3858 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3859 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3860 wine_dbgstr_longlong(systime));
3862 /* STOPPED -> RUNNING */
3863 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3864 ok(hr == S_OK, "Failed to stop source, hr %#lx.\n", hr);
3866 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3867 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3868 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3869 wine_dbgstr_longlong(systime));
3871 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3872 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3874 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3875 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3876 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3877 wine_dbgstr_longlong(systime));
3879 /* PAUSED -> RUNNING */
3880 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3881 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3883 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3884 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3885 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3886 wine_dbgstr_longlong(systime));
3888 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3889 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3891 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3892 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3893 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3894 wine_dbgstr_longlong(systime));
3896 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3897 ok(hr == S_OK, "Failed to pause source, hr %#lx.\n", hr);
3899 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3900 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3901 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3902 wine_dbgstr_longlong(systime));
3904 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3905 ok(hr == S_OK, "Failed to start source, hr %#lx.\n", hr);
3907 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3908 ok(hr == S_OK, "Failed to get time %#lx.\n", hr);
3909 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3910 wine_dbgstr_longlong(systime));
3912 IMFClockStateSink_Release(statesink);
3913 IMFPresentationTimeSource_Release(time_source);
3916 static void test_MFInvokeCallback(void)
3918 struct test_callback *callback;
3919 IMFAsyncResult *result;
3920 MFASYNCRESULT *data;
3921 ULONG refcount;
3922 HRESULT hr;
3923 DWORD ret;
3925 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3926 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
3928 callback = create_test_callback(NULL);
3930 hr = MFCreateAsyncResult(NULL, &callback->IMFAsyncCallback_iface, NULL, &result);
3931 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
3933 data = (MFASYNCRESULT *)result;
3934 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3935 ok(data->hEvent != NULL, "Failed to create event.\n");
3937 hr = MFInvokeCallback(result);
3938 ok(hr == S_OK, "Failed to invoke, hr %#lx.\n", hr);
3940 ret = WaitForSingleObject(data->hEvent, 100);
3941 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#lx.\n", ret);
3943 refcount = IMFAsyncResult_Release(result);
3944 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
3946 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
3948 hr = MFShutdown();
3949 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
3952 static void test_stream_descriptor(void)
3954 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3955 IMFMediaTypeHandler *type_handler;
3956 IMFStreamDescriptor *stream_desc;
3957 GUID major_type;
3958 DWORD id, count;
3959 unsigned int i;
3960 HRESULT hr;
3962 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3963 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3965 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3967 hr = MFCreateMediaType(&media_types[i]);
3968 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
3971 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3972 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
3974 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3975 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
3977 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3978 ok(hr == S_OK, "Failed to get descriptor id, hr %#lx.\n", hr);
3979 ok(id == 123, "Unexpected id %#lx.\n", id);
3981 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3982 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
3984 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3985 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
3986 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3988 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3989 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
3991 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3992 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
3994 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3996 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3997 ok(hr == S_OK, "Failed to get media type, hr %#lx.\n", hr);
3998 ok(media_type == media_types[i], "Unexpected object.\n");
4000 if (SUCCEEDED(hr))
4001 IMFMediaType_Release(media_type);
4004 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
4005 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#lx.\n", hr);
4007 /* IsMediaTypeSupported() */
4009 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
4010 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4012 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
4013 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4015 hr = MFCreateMediaType(&media_type);
4016 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4018 hr = MFCreateMediaType(&media_type3);
4019 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4021 media_type2 = (void *)0xdeadbeef;
4022 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4023 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4024 ok(!media_type2, "Unexpected pointer.\n");
4026 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
4027 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4029 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
4030 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4032 media_type2 = (void *)0xdeadbeef;
4033 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4034 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4035 ok(!media_type2, "Unexpected pointer.\n");
4037 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4038 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4040 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4041 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4043 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4044 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4045 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
4047 /* Mismatching major types. */
4048 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4049 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4051 media_type2 = (void *)0xdeadbeef;
4052 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4053 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4054 ok(!media_type2, "Unexpected pointer.\n");
4056 /* Subtype missing. */
4057 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4058 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4060 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4061 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4063 media_type2 = (void *)0xdeadbeef;
4064 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4065 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4066 ok(!media_type2, "Unexpected pointer.\n");
4068 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4069 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4071 media_type2 = (void *)0xdeadbeef;
4072 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4073 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4074 ok(!media_type2, "Unexpected pointer.\n");
4076 /* Mismatching subtype. */
4077 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4078 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4080 media_type2 = (void *)0xdeadbeef;
4081 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4082 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4083 ok(!media_type2, "Unexpected pointer.\n");
4085 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
4086 ok(hr == S_OK, "Failed to get type count, hr %#lx.\n", hr);
4087 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
4089 IMFMediaTypeHandler_Release(type_handler);
4090 IMFStreamDescriptor_Release(stream_desc);
4092 /* IsMediaTypeSupported() for unset current type. */
4093 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
4094 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4096 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4097 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4099 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
4100 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4102 /* Initialize one from initial type set. */
4103 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
4104 ok(hr == S_OK, "Failed to copy attributes, 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 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4112 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4114 media_type2 = (void *)0xdeadbeef;
4115 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4116 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
4117 ok(!media_type2, "Unexpected pointer.\n");
4119 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
4120 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4122 media_type2 = (void *)0xdeadbeef;
4123 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4124 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4125 ok(!media_type2, "Unexpected pointer.\n");
4127 /* Now set current type that's not compatible. */
4128 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4129 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4131 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
4132 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4134 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
4135 ok(hr == S_OK, "Failed to set current type, hr %#lx.\n", hr);
4137 media_type2 = (void *)0xdeadbeef;
4138 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
4139 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4140 ok(!media_type2, "Unexpected pointer.\n");
4142 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
4143 ok(hr == S_OK, "Failed to copy attributes, hr %#lx.\n", hr);
4145 media_type2 = (void *)0xdeadbeef;
4146 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
4147 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4148 ok(!media_type2, "Unexpected pointer.\n");
4150 IMFMediaType_Release(media_type);
4151 IMFMediaType_Release(media_type3);
4153 IMFMediaTypeHandler_Release(type_handler);
4155 IMFStreamDescriptor_Release(stream_desc);
4157 /* Major type is returned for first entry. */
4158 hr = MFCreateMediaType(&media_types[0]);
4159 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4160 hr = MFCreateMediaType(&media_types[1]);
4161 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4163 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4164 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4165 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4166 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4168 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
4169 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4171 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
4172 ok(hr == S_OK, "Failed to get type handler, hr %#lx.\n", hr);
4174 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4175 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4176 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4178 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4180 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4181 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4183 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
4184 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4185 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
4187 IMFMediaType_Release(media_types[0]);
4188 IMFMediaType_Release(media_types[1]);
4190 IMFMediaTypeHandler_Release(type_handler);
4191 IMFStreamDescriptor_Release(stream_desc);
4194 static const struct image_size_test
4196 const GUID *subtype;
4197 UINT32 width;
4198 UINT32 height;
4199 UINT32 size;
4200 UINT32 plane_size; /* Matches image size when 0. */
4202 image_size_tests[] =
4204 { &MFVideoFormat_RGB8, 3, 5, 20 },
4205 { &MFVideoFormat_RGB8, 1, 1, 4 },
4206 { &MFVideoFormat_RGB555, 3, 5, 40 },
4207 { &MFVideoFormat_RGB555, 1, 1, 4 },
4208 { &MFVideoFormat_RGB565, 3, 5, 40 },
4209 { &MFVideoFormat_RGB565, 1, 1, 4 },
4210 { &MFVideoFormat_RGB24, 3, 5, 60 },
4211 { &MFVideoFormat_RGB24, 1, 1, 4 },
4212 { &MFVideoFormat_RGB32, 3, 5, 60 },
4213 { &MFVideoFormat_RGB32, 1, 1, 4 },
4214 { &MFVideoFormat_ARGB32, 3, 5, 60 },
4215 { &MFVideoFormat_ARGB32, 1, 1, 4 },
4216 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
4217 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
4218 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
4219 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
4221 /* YUV */
4222 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
4223 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
4224 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
4225 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
4226 { &MFVideoFormat_NV12, 4, 2, 12 },
4227 { &MFVideoFormat_NV12, 320, 240, 115200 },
4228 { &MFVideoFormat_AYUV, 1, 1, 4 },
4229 { &MFVideoFormat_AYUV, 2, 1, 8 },
4230 { &MFVideoFormat_AYUV, 1, 2, 8 },
4231 { &MFVideoFormat_AYUV, 4, 3, 48 },
4232 { &MFVideoFormat_AYUV, 320, 240, 307200 },
4233 { &MFVideoFormat_IMC1, 1, 1, 4 },
4234 { &MFVideoFormat_IMC1, 2, 1, 4 },
4235 { &MFVideoFormat_IMC1, 1, 2, 8 },
4236 { &MFVideoFormat_IMC1, 4, 3, 24 },
4237 { &MFVideoFormat_IMC1, 320, 240, 153600 },
4238 { &MFVideoFormat_IMC3, 1, 1, 4 },
4239 { &MFVideoFormat_IMC3, 2, 1, 4 },
4240 { &MFVideoFormat_IMC3, 1, 2, 8 },
4241 { &MFVideoFormat_IMC3, 4, 3, 24 },
4242 { &MFVideoFormat_IMC3, 320, 240, 153600 },
4243 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
4244 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
4245 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
4246 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
4247 { &MFVideoFormat_IMC2, 4, 2, 12 },
4248 { &MFVideoFormat_IMC2, 320, 240, 115200 },
4249 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
4250 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
4251 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
4252 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
4253 { &MFVideoFormat_IMC4, 4, 2, 12 },
4254 { &MFVideoFormat_IMC4, 320, 240, 115200 },
4255 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
4256 { &MFVideoFormat_YV12, 2, 1, 3 },
4257 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
4258 { &MFVideoFormat_YV12, 4, 3, 18 },
4259 { &MFVideoFormat_YV12, 320, 240, 115200 },
4261 { &MFVideoFormat_I420, 1, 1, 3, 1 },
4262 { &MFVideoFormat_I420, 2, 1, 3 },
4263 { &MFVideoFormat_I420, 1, 2, 6, 3 },
4264 { &MFVideoFormat_I420, 4, 3, 18 },
4265 { &MFVideoFormat_I420, 320, 240, 115200 },
4267 { &MFVideoFormat_IYUV, 1, 1, 3, 1 },
4268 { &MFVideoFormat_IYUV, 2, 1, 3 },
4269 { &MFVideoFormat_IYUV, 1, 2, 6, 3 },
4270 { &MFVideoFormat_IYUV, 4, 3, 18 },
4271 { &MFVideoFormat_IYUV, 320, 240, 115200 },
4273 { &MFVideoFormat_YUY2, 2, 1, 4 },
4274 { &MFVideoFormat_YUY2, 4, 3, 24 },
4275 { &MFVideoFormat_YUY2, 128, 128, 32768 },
4276 { &MFVideoFormat_YUY2, 320, 240, 153600 },
4278 { &MFVideoFormat_UYVY, 2, 1, 4 },
4279 { &MFVideoFormat_UYVY, 4, 3, 24 },
4280 { &MFVideoFormat_UYVY, 128, 128, 32768 },
4281 { &MFVideoFormat_UYVY, 320, 240, 153600 },
4284 static void test_MFCalculateImageSize(void)
4286 DWORD plane_size;
4287 unsigned int i;
4288 UINT32 size;
4289 HRESULT hr;
4291 size = 1;
4292 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4293 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#lx.\n", hr);
4294 ok(size == 0, "Unexpected size %u.\n", size);
4296 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4298 const struct image_size_test *ptr = &image_size_tests[i];
4300 /* Those are supported since Win10. */
4301 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4302 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4304 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4305 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#lx.\n", i, hr);
4306 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4307 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4309 if (pMFGetPlaneSize)
4311 unsigned int expected = ptr->plane_size ? ptr->plane_size : ptr->size;
4313 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &plane_size);
4314 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4315 ok(plane_size == expected, "%u: unexpected plane size %lu, expected %u.\n", i, plane_size, expected);
4320 static void test_MFGetPlaneSize(void)
4322 unsigned int i;
4323 DWORD size;
4324 HRESULT hr;
4326 if (!pMFGetPlaneSize)
4328 win_skip("MFGetPlaneSize() is not available.\n");
4329 return;
4332 size = 1;
4333 hr = pMFGetPlaneSize(0xdeadbeef, 64, 64, &size);
4334 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
4335 ok(size == 0, "Unexpected size %lu.\n", size);
4337 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4339 const struct image_size_test *ptr = &image_size_tests[i];
4340 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4342 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4343 ok(hr == S_OK, "%u: failed to get plane size, hr %#lx.\n", i, hr);
4344 ok(size == plane_size, "%u: unexpected plane size %lu, expected %u.\n", i, size, plane_size);
4348 static void test_MFCompareFullToPartialMediaType(void)
4350 IMFMediaType *full_type, *partial_type;
4351 HRESULT hr;
4352 BOOL ret;
4354 hr = MFCreateMediaType(&full_type);
4355 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4357 hr = MFCreateMediaType(&partial_type);
4358 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4360 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4361 ok(!ret, "Unexpected result %d.\n", ret);
4363 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4364 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4366 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4367 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4369 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4370 ok(ret, "Unexpected result %d.\n", ret);
4372 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4373 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4375 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4376 ok(ret, "Unexpected result %d.\n", ret);
4378 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4379 ok(hr == S_OK, "Failed to set major type, hr %#lx.\n", hr);
4381 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4382 ok(!ret, "Unexpected result %d.\n", ret);
4384 IMFMediaType_Release(full_type);
4385 IMFMediaType_Release(partial_type);
4388 static void test_attributes_serialization(void)
4390 static const UINT8 blob[] = {1,2,3};
4391 IMFAttributes *attributes, *dest;
4392 UINT32 size, count, value32;
4393 double value_dbl;
4394 UINT64 value64;
4395 UINT8 *buffer;
4396 IUnknown *obj;
4397 HRESULT hr;
4398 WCHAR *str;
4399 GUID guid;
4401 hr = MFCreateAttributes(&attributes, 0);
4402 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4404 hr = MFCreateAttributes(&dest, 0);
4405 ok(hr == S_OK, "Failed to create object, hr %#lx.\n", hr);
4407 hr = MFGetAttributesAsBlobSize(attributes, &size);
4408 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4409 ok(size == 8, "Got size %u.\n", size);
4411 buffer = malloc(size);
4413 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4414 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4416 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4417 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#lx.\n", hr);
4419 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4420 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4422 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4423 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4425 hr = MFInitAttributesFromBlob(dest, buffer, size);
4426 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4428 /* Previous items are cleared. */
4429 hr = IMFAttributes_GetCount(dest, &count);
4430 ok(hr == S_OK, "Failed to get attribute count, hr %#lx.\n", hr);
4431 ok(count == 0, "Unexpected count %u.\n", count);
4433 free(buffer);
4435 /* Set some attributes of various types. */
4436 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4437 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4438 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4439 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4440 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4441 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4442 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4444 hr = MFGetAttributesAsBlobSize(attributes, &size);
4445 ok(hr == S_OK, "Failed to get blob size, hr %#lx.\n", hr);
4446 ok(size > 8, "Got unexpected size %u.\n", size);
4448 buffer = malloc(size);
4449 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4450 ok(hr == S_OK, "Failed to serialize, hr %#lx.\n", hr);
4451 hr = MFInitAttributesFromBlob(dest, buffer, size);
4452 ok(hr == S_OK, "Failed to deserialize, hr %#lx.\n", hr);
4453 free(buffer);
4455 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4456 ok(hr == S_OK, "Failed to get get uint32 value, hr %#lx.\n", hr);
4457 ok(value32 == 456, "Unexpected value %u.\n", value32);
4458 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4459 ok(hr == S_OK, "Failed to get get uint64 value, hr %#lx.\n", hr);
4460 ok(value64 == 123, "Unexpected value.\n");
4461 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4462 ok(hr == S_OK, "Failed to get get double value, hr %#lx.\n", hr);
4463 ok(value_dbl == 0.5, "Unexpected value.\n");
4464 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4465 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4466 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4467 ok(hr == S_OK, "Failed to get guid value, hr %#lx.\n", hr);
4468 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4469 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4470 ok(hr == S_OK, "Failed to get string value, hr %#lx.\n", hr);
4471 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4472 CoTaskMemFree(str);
4473 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4474 ok(hr == S_OK, "Failed to get blob value, hr %#lx.\n", hr);
4475 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4476 CoTaskMemFree(buffer);
4478 IMFAttributes_Release(attributes);
4479 IMFAttributes_Release(dest);
4482 static void test_wrapped_media_type(void)
4484 IMFMediaType *mediatype, *mediatype2;
4485 UINT32 count, type;
4486 HRESULT hr;
4487 GUID guid;
4489 hr = MFCreateMediaType(&mediatype);
4490 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4492 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4493 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4495 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4496 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4497 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4498 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4500 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4501 ok(hr == S_OK, "Failed to set GUID value, hr %#lx.\n", hr);
4503 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4504 ok(hr == S_OK, "Failed to create wrapped media type, hr %#lx.\n", hr);
4506 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4507 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4508 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4510 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4511 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
4512 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4514 hr = IMFMediaType_GetCount(mediatype2, &count);
4515 ok(hr == S_OK, "Failed to get item count, hr %#lx.\n", hr);
4516 ok(count == 3, "Unexpected count %u.\n", count);
4518 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4519 ok(hr == S_OK, "Failed to get item type, hr %#lx.\n", hr);
4520 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4522 IMFMediaType_Release(mediatype);
4524 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4525 ok(hr == S_OK, "Failed to unwrap, hr %#lx.\n", hr);
4527 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4528 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
4529 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4531 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4532 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4534 IMFMediaType_Release(mediatype);
4535 IMFMediaType_Release(mediatype2);
4538 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4540 static const struct wave_fmt_test
4542 const GUID *subtype;
4543 WORD format_tag;
4545 wave_fmt_tests[] =
4547 { &MFAudioFormat_PCM, WAVE_FORMAT_PCM, },
4548 { &MFAudioFormat_Float, WAVE_FORMAT_IEEE_FLOAT, },
4550 WAVEFORMATEXTENSIBLE *format_ext;
4551 IMFMediaType *mediatype;
4552 WAVEFORMATEX *format;
4553 UINT32 size, i;
4554 HRESULT hr;
4556 hr = MFCreateMediaType(&mediatype);
4557 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
4559 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4560 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4562 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4563 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4565 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4566 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
4568 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4569 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4571 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4572 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4574 for (i = 0; i < ARRAY_SIZE(wave_fmt_tests); ++i)
4576 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, wave_fmt_tests[i].subtype);
4577 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
4579 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4580 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4581 ok(format != NULL, "Expected format structure.\n");
4582 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4583 ok(format->wFormatTag == wave_fmt_tests[i].format_tag, "Expected tag %u, got %u.\n", wave_fmt_tests[i].format_tag, format->wFormatTag);
4584 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4585 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format->nSamplesPerSec);
4586 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n", format->nAvgBytesPerSec);
4587 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4588 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4589 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4590 CoTaskMemFree(format);
4592 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4593 MFWaveFormatExConvertFlag_ForceExtensible);
4594 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4595 ok(format_ext != NULL, "Expected format structure.\n");
4596 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4597 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4598 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4599 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %lu.\n", format_ext->Format.nSamplesPerSec);
4600 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %lu.\n",
4601 format_ext->Format.nAvgBytesPerSec);
4602 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4603 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4604 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4605 format_ext->Format.cbSize);
4606 CoTaskMemFree(format_ext);
4608 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4609 ok(hr == S_OK, "Failed to create format, hr %#lx.\n", hr);
4610 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4611 CoTaskMemFree(format);
4614 IMFMediaType_Release(mediatype);
4617 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4619 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4620 IMFByteStream *stream;
4621 IUnknown *object;
4622 HRESULT hr;
4624 ok(!!result, "Unexpected result object.\n");
4626 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4628 hr = IMFAsyncResult_GetObject(result, &object);
4629 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
4631 hr = MFEndCreateFile(result, &stream);
4632 ok(hr == S_OK, "Failed to get file stream, hr %#lx.\n", hr);
4633 IMFByteStream_Release(stream);
4635 SetEvent(callback->event);
4637 return S_OK;
4640 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4642 testcallback_QueryInterface,
4643 testcallback_AddRef,
4644 testcallback_Release,
4645 testcallback_GetParameters,
4646 test_create_file_callback_Invoke,
4649 static void test_async_create_file(void)
4651 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4652 struct test_callback *callback;
4653 IUnknown *cancel_cookie;
4654 HRESULT hr;
4655 BOOL ret;
4657 callback = create_test_callback(&test_create_file_callback_vtbl);
4659 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4660 ok(hr == S_OK, "Fail to start up, hr %#lx.\n", hr);
4662 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
4664 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4665 GetTempFileNameW(pathW, NULL, 0, fileW);
4667 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4668 &callback->IMFAsyncCallback_iface, (IUnknown *)&callback->IMFAsyncCallback_iface, &cancel_cookie);
4669 ok(hr == S_OK, "Async create request failed, hr %#lx.\n", hr);
4670 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4672 WaitForSingleObject(callback->event, INFINITE);
4674 IUnknown_Release(cancel_cookie);
4676 CloseHandle(callback->event);
4678 hr = MFShutdown();
4679 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
4681 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
4683 ret = DeleteFileW(fileW);
4684 ok(ret, "Failed to delete test file.\n");
4687 struct activate_object
4689 IMFActivate IMFActivate_iface;
4690 LONG refcount;
4693 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4695 if (IsEqualIID(riid, &IID_IMFActivate) ||
4696 IsEqualIID(riid, &IID_IMFAttributes) ||
4697 IsEqualIID(riid, &IID_IUnknown))
4699 *obj = iface;
4700 IMFActivate_AddRef(iface);
4701 return S_OK;
4704 *obj = NULL;
4705 return E_NOINTERFACE;
4708 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4710 return 2;
4713 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4715 return 1;
4718 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4720 return E_NOTIMPL;
4723 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4725 return E_NOTIMPL;
4728 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4730 return E_NOTIMPL;
4733 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4734 BOOL *result)
4736 return E_NOTIMPL;
4739 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4741 return E_NOTIMPL;
4744 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4746 return E_NOTIMPL;
4749 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4751 return E_NOTIMPL;
4754 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4756 return E_NOTIMPL;
4759 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4761 return E_NOTIMPL;
4764 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4765 UINT32 size, UINT32 *length)
4767 return E_NOTIMPL;
4770 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4771 WCHAR **value, UINT32 *length)
4773 return E_NOTIMPL;
4776 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4778 return E_NOTIMPL;
4781 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4782 UINT32 bufsize, UINT32 *blobsize)
4784 return E_NOTIMPL;
4787 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4789 return E_NOTIMPL;
4792 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4794 return E_NOTIMPL;
4797 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4799 return E_NOTIMPL;
4802 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4804 return E_NOTIMPL;
4807 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4809 return E_NOTIMPL;
4812 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4814 return E_NOTIMPL;
4817 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4819 return E_NOTIMPL;
4822 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4824 return E_NOTIMPL;
4827 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4829 return E_NOTIMPL;
4832 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4834 return E_NOTIMPL;
4837 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4839 return E_NOTIMPL;
4842 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4844 return E_NOTIMPL;
4847 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4849 return E_NOTIMPL;
4852 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4854 return E_NOTIMPL;
4857 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4859 return E_NOTIMPL;
4862 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4864 return E_NOTIMPL;
4867 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4869 return E_NOTIMPL;
4872 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4874 return E_NOTIMPL;
4877 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4879 return E_NOTIMPL;
4882 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4884 return E_NOTIMPL;
4887 static const IMFActivateVtbl activate_object_vtbl =
4889 activate_object_QueryInterface,
4890 activate_object_AddRef,
4891 activate_object_Release,
4892 activate_object_GetItem,
4893 activate_object_GetItemType,
4894 activate_object_CompareItem,
4895 activate_object_Compare,
4896 activate_object_GetUINT32,
4897 activate_object_GetUINT64,
4898 activate_object_GetDouble,
4899 activate_object_GetGUID,
4900 activate_object_GetStringLength,
4901 activate_object_GetString,
4902 activate_object_GetAllocatedString,
4903 activate_object_GetBlobSize,
4904 activate_object_GetBlob,
4905 activate_object_GetAllocatedBlob,
4906 activate_object_GetUnknown,
4907 activate_object_SetItem,
4908 activate_object_DeleteItem,
4909 activate_object_DeleteAllItems,
4910 activate_object_SetUINT32,
4911 activate_object_SetUINT64,
4912 activate_object_SetDouble,
4913 activate_object_SetGUID,
4914 activate_object_SetString,
4915 activate_object_SetBlob,
4916 activate_object_SetUnknown,
4917 activate_object_LockStore,
4918 activate_object_UnlockStore,
4919 activate_object_GetCount,
4920 activate_object_GetItemByIndex,
4921 activate_object_CopyAllItems,
4922 activate_object_ActivateObject,
4923 activate_object_ShutdownObject,
4924 activate_object_DetachObject,
4927 static void test_local_handlers(void)
4929 IMFActivate local_activate = { &activate_object_vtbl };
4930 static const WCHAR localW[] = L"local";
4931 HRESULT hr;
4933 if (!pMFRegisterLocalSchemeHandler)
4935 win_skip("Local handlers are not supported.\n");
4936 return;
4939 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4940 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4942 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4943 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4945 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4946 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4948 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4949 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
4951 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4952 ok(hr == S_OK, "Failed to register scheme handler, hr %#lx.\n", hr);
4954 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4955 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4957 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4958 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4960 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4961 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4963 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4964 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4966 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4967 ok(hr == S_OK, "Failed to register stream handler, hr %#lx.\n", hr);
4970 static void test_create_property_store(void)
4972 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4973 IPropertyStore *store, *store2;
4974 PROPVARIANT value = {0};
4975 PROPERTYKEY key;
4976 ULONG refcount;
4977 DWORD count;
4978 HRESULT hr;
4980 hr = CreatePropertyStore(NULL);
4981 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4983 hr = CreatePropertyStore(&store);
4984 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
4986 hr = CreatePropertyStore(&store2);
4987 ok(hr == S_OK, "Failed to create property store, hr %#lx.\n", hr);
4988 ok(store2 != store, "Expected different store objects.\n");
4989 IPropertyStore_Release(store2);
4991 check_interface(store, &IID_IPropertyStoreCache, FALSE);
4992 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
4994 hr = IPropertyStore_GetCount(store, NULL);
4995 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
4997 count = 0xdeadbeef;
4998 hr = IPropertyStore_GetCount(store, &count);
4999 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5000 ok(!count, "Unexpected count %lu.\n", count);
5002 hr = IPropertyStore_Commit(store);
5003 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5005 hr = IPropertyStore_GetAt(store, 0, &key);
5006 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5008 hr = IPropertyStore_GetValue(store, NULL, &value);
5009 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5011 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
5012 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5014 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5015 ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
5017 memset(&value, 0, sizeof(PROPVARIANT));
5018 value.vt = VT_I4;
5019 value.lVal = 0xdeadbeef;
5020 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5021 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5023 if (0)
5025 /* crashes on Windows */
5026 hr = IPropertyStore_SetValue(store, NULL, &value);
5027 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5030 hr = IPropertyStore_GetCount(store, &count);
5031 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5032 ok(count == 1, "Unexpected count %lu.\n", count);
5034 hr = IPropertyStore_Commit(store);
5035 ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr);
5037 hr = IPropertyStore_GetAt(store, 0, &key);
5038 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5039 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
5041 hr = IPropertyStore_GetAt(store, 1, &key);
5042 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5044 memset(&value, 0xcc, sizeof(PROPVARIANT));
5045 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5046 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5047 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
5048 ok(value.lVal == 0xdeadbeef, "Unexpected value %#lx.\n", value.lVal);
5050 memset(&value, 0, sizeof(PROPVARIANT));
5051 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
5052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5054 hr = IPropertyStore_GetCount(store, &count);
5055 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5056 ok(count == 1, "Unexpected count %lu.\n", count);
5058 memset(&value, 0xcc, sizeof(PROPVARIANT));
5059 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
5060 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5061 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
5062 ok(!value.lVal, "Unexpected value %#lx.\n", value.lVal);
5064 refcount = IPropertyStore_Release(store);
5065 ok(!refcount, "Unexpected refcount %lu.\n", refcount);
5068 struct test_thread_param
5070 IMFDXGIDeviceManager *manager;
5071 HANDLE handle;
5072 BOOL lock;
5075 static DWORD WINAPI test_device_manager_thread(void *arg)
5077 struct test_thread_param *param = arg;
5078 ID3D11Device *device;
5079 HRESULT hr;
5081 if (param->lock)
5083 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
5084 (void **)&device, FALSE);
5085 if (SUCCEEDED(hr))
5086 ID3D11Device_Release(device);
5088 else
5089 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
5091 return hr;
5094 static void test_dxgi_device_manager(void)
5096 IMFDXGIDeviceManager *manager, *manager2;
5097 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
5098 struct test_thread_param param;
5099 HANDLE handle1, handle, thread;
5100 UINT token, token2;
5101 IUnknown *unk;
5102 HRESULT hr;
5104 if (!pMFCreateDXGIDeviceManager)
5106 win_skip("MFCreateDXGIDeviceManager not found.\n");
5107 return;
5110 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
5111 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5113 token = 0;
5114 hr = pMFCreateDXGIDeviceManager(&token, NULL);
5115 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#lx.\n", hr);
5116 ok(!token, "got wrong token: %u.\n", token);
5118 hr = pMFCreateDXGIDeviceManager(&token, &manager);
5119 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5120 EXPECT_REF(manager, 1);
5121 ok(!!token, "got wrong token: %u.\n", token);
5123 Sleep(50);
5124 token2 = 0;
5125 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
5126 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#lx.\n", hr);
5127 EXPECT_REF(manager2, 1);
5128 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
5129 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
5130 EXPECT_REF(manager, 1);
5132 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5133 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5135 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5136 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
5138 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
5139 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5141 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
5142 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
5143 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5144 EXPECT_REF(d3d11_dev, 1);
5146 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
5147 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5148 EXPECT_REF(d3d11_dev, 1);
5150 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
5151 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5153 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5154 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5155 EXPECT_REF(manager, 1);
5156 EXPECT_REF(d3d11_dev, 2);
5158 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
5159 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#lx.\n", hr);
5160 EXPECT_REF(manager2, 1);
5161 EXPECT_REF(d3d11_dev, 2);
5163 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
5164 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5165 EXPECT_REF(manager, 1);
5166 EXPECT_REF(d3d11_dev, 2);
5168 /* GetVideoService() on device change. */
5169 handle = NULL;
5170 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5171 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5172 ok(!!handle, "Unexpected handle value %p.\n", handle);
5174 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
5175 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
5176 ok(hr == S_OK, "D3D11CreateDevice failed: %#lx.\n", hr);
5177 EXPECT_REF(d3d11_dev2, 1);
5178 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
5179 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#lx.\n", hr);
5180 EXPECT_REF(manager, 1);
5181 EXPECT_REF(d3d11_dev2, 2);
5182 EXPECT_REF(d3d11_dev, 1);
5184 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5185 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#lx.\n", hr);
5187 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5188 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5190 handle = NULL;
5191 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5192 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5193 ok(!!handle, "Unexpected handle value %p.\n", handle);
5195 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
5196 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5198 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
5199 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5200 IUnknown_Release(unk);
5202 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
5203 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5204 IUnknown_Release(unk);
5206 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
5207 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5208 IUnknown_Release(unk);
5210 handle1 = NULL;
5211 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5212 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5213 ok(handle != handle1, "Unexpected handle.\n");
5215 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5216 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5218 /* Already closed. */
5219 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5220 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5222 handle = NULL;
5223 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5224 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5226 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5227 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5229 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
5230 ok(hr == E_HANDLE, "Unexpected hr %#lx.\n", hr);
5232 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5233 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5234 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
5235 ID3D11Device_Release(device);
5237 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5238 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5240 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5241 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5243 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
5244 ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr);
5246 /* Locked with one handle, unlock with another. */
5247 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5248 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5250 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5251 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5253 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5254 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5256 ID3D11Device_Release(device);
5258 /* Closing unlocks the device. */
5259 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5260 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5262 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5263 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5264 ID3D11Device_Release(device);
5266 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5267 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5269 /* Open two handles. */
5270 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
5271 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5273 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
5274 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5276 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5277 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5278 ID3D11Device_Release(device);
5280 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
5281 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5282 ID3D11Device_Release(device);
5284 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5285 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5287 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
5288 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5290 param.manager = manager;
5291 param.handle = handle;
5292 param.lock = TRUE;
5293 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5294 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5295 GetExitCodeThread(thread, (DWORD *)&hr);
5296 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#lx.\n", hr);
5297 CloseHandle(thread);
5299 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5300 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5302 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
5303 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
5305 /* Lock on main thread, unlock on another. */
5306 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
5307 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5308 ID3D11Device_Release(device);
5310 param.manager = manager;
5311 param.handle = handle;
5312 param.lock = FALSE;
5313 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
5314 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
5315 GetExitCodeThread(thread, (DWORD *)&hr);
5316 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5317 CloseHandle(thread);
5319 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
5320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5322 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
5323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5325 IMFDXGIDeviceManager_Release(manager);
5326 EXPECT_REF(d3d11_dev2, 1);
5327 ID3D11Device_Release(d3d11_dev);
5328 ID3D11Device_Release(d3d11_dev2);
5329 IMFDXGIDeviceManager_Release(manager2);
5332 static void test_MFCreateTransformActivate(void)
5334 IMFActivate *activate;
5335 UINT32 count;
5336 HRESULT hr;
5338 if (!pMFCreateTransformActivate)
5340 win_skip("MFCreateTransformActivate() is not available.\n");
5341 return;
5344 hr = pMFCreateTransformActivate(&activate);
5345 ok(hr == S_OK, "Failed to create activator, hr %#lx.\n", hr);
5347 hr = IMFActivate_GetCount(activate, &count);
5348 ok(hr == S_OK, "Failed to get count, hr %#lx.\n", hr);
5349 ok(!count, "Unexpected attribute count %u.\n", count);
5351 IMFActivate_Release(activate);
5354 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5356 if (IsEqualIID(riid, &IID_IClassFactory) ||
5357 IsEqualIID(riid, &IID_IUnknown))
5359 *obj = iface;
5360 IClassFactory_AddRef(iface);
5361 return S_OK;
5364 *obj = NULL;
5365 return E_NOINTERFACE;
5368 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5370 return 2;
5373 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5375 return 1;
5378 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5380 ok(0, "Unexpected call.\n");
5381 return E_NOTIMPL;
5384 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5386 return S_OK;
5389 static const IClassFactoryVtbl test_mft_factory_vtbl =
5391 test_mft_factory_QueryInterface,
5392 test_mft_factory_AddRef,
5393 test_mft_factory_Release,
5394 test_mft_factory_CreateInstance,
5395 test_mft_factory_LockServer,
5398 static void test_MFTRegisterLocal(void)
5400 IClassFactory test_factory = { &test_mft_factory_vtbl };
5401 MFT_REGISTER_TYPE_INFO input_types[1], *in_types, *out_types;
5402 IMFAttributes *attributes;
5403 IMFActivate **activate;
5404 UINT32 count, count2;
5405 WCHAR *name;
5406 HRESULT hr;
5408 if (!pMFTRegisterLocal)
5410 win_skip("MFTRegisterLocal() is not available.\n");
5411 return;
5414 input_types[0].guidMajorType = MFMediaType_Audio;
5415 input_types[0].guidSubtype = MFAudioFormat_PCM;
5416 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5417 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5419 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5420 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5422 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5423 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5424 ok(count > 0, "Unexpected count %u.\n", count);
5425 CoTaskMemFree(activate);
5427 hr = pMFTUnregisterLocal(&test_factory);
5428 ok(hr == S_OK, "Failed to unregister MFT, hr %#lx.\n", hr);
5430 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5431 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5432 ok(count2 < count, "Unexpected count %u.\n", count2);
5433 CoTaskMemFree(activate);
5435 hr = pMFTUnregisterLocal(&test_factory);
5436 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5438 hr = pMFTUnregisterLocal(NULL);
5439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5441 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5442 0, NULL);
5443 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5445 hr = MFTGetInfo(MFT_CATEGORY_OTHER, &name, &in_types, &count, &out_types, &count2, &attributes);
5446 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5448 hr = pMFTUnregisterLocal(NULL);
5449 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5451 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5452 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#lx.\n", hr);
5454 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5455 0, NULL);
5456 ok(hr == S_OK, "Failed to register MFT, hr %#lx.\n", hr);
5458 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5459 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5462 static void test_queue_com(void)
5464 static int system_queues[] =
5466 MFASYNC_CALLBACK_QUEUE_STANDARD,
5467 MFASYNC_CALLBACK_QUEUE_RT,
5468 MFASYNC_CALLBACK_QUEUE_IO,
5469 MFASYNC_CALLBACK_QUEUE_TIMER,
5470 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5471 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5474 static int user_queues[] =
5476 MF_STANDARD_WORKQUEUE,
5477 MF_WINDOW_WORKQUEUE,
5478 MF_MULTITHREADED_WORKQUEUE,
5481 char path_name[MAX_PATH];
5482 PROCESS_INFORMATION info;
5483 STARTUPINFOA startup;
5484 char **argv;
5485 int i;
5487 if (!pCoGetApartmentType)
5489 win_skip("CoGetApartmentType() is not available.\n");
5490 return;
5493 winetest_get_mainargs(&argv);
5495 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5497 memset(&startup, 0, sizeof(startup));
5498 startup.cb = sizeof(startup);
5499 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5500 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5501 "CreateProcess failed.\n" );
5502 wait_child_process(info.hProcess);
5503 CloseHandle(info.hProcess);
5504 CloseHandle(info.hThread);
5507 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5509 memset(&startup, 0, sizeof(startup));
5510 startup.cb = sizeof(startup);
5511 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5512 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5513 "CreateProcess failed.\n" );
5514 wait_child_process(info.hProcess);
5515 CloseHandle(info.hProcess);
5516 CloseHandle(info.hThread);
5520 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5522 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5523 APTTYPEQUALIFIER qualifier;
5524 APTTYPE com_type;
5525 HRESULT hr;
5527 hr = pCoGetApartmentType(&com_type, &qualifier);
5528 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#lx.\n", hr);
5529 if (SUCCEEDED(hr))
5531 todo_wine {
5532 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5533 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5534 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5535 else
5536 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5537 "%#lx: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5541 SetEvent(callback->event);
5542 return S_OK;
5545 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5547 testcallback_QueryInterface,
5548 testcallback_AddRef,
5549 testcallback_Release,
5550 testcallback_GetParameters,
5551 test_queue_com_state_callback_Invoke,
5554 static void test_queue_com_state(const char *name)
5556 struct test_callback *callback;
5557 DWORD queue, queue_type;
5558 HRESULT hr;
5560 callback = create_test_callback(&test_queue_com_state_callback_vtbl);
5561 callback->event = CreateEventA(NULL, FALSE, FALSE, NULL);
5563 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5564 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
5566 if (name[0] == 's')
5568 callback->param = name[1] - '0';
5569 hr = MFPutWorkItem(callback->param, &callback->IMFAsyncCallback_iface, NULL);
5570 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5571 WaitForSingleObject(callback->event, INFINITE);
5573 else if (name[0] == 'u')
5575 queue_type = name[1] - '0';
5577 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5578 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5579 "Failed to allocate a queue of type %lu, hr %#lx.\n", queue_type, hr);
5581 if (SUCCEEDED(hr))
5583 callback->param = queue;
5584 hr = MFPutWorkItem(queue, &callback->IMFAsyncCallback_iface, NULL);
5585 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#lx.\n", hr);
5586 WaitForSingleObject(callback->event, INFINITE);
5588 hr = MFUnlockWorkQueue(queue);
5589 ok(hr == S_OK, "Failed to unlock the queue, hr %#lx.\n", hr);
5593 CloseHandle(callback->event);
5595 hr = MFShutdown();
5596 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
5598 IMFAsyncCallback_Release(&callback->IMFAsyncCallback_iface);
5601 static void test_MFGetStrideForBitmapInfoHeader(void)
5603 static const struct stride_test
5605 const GUID *subtype;
5606 unsigned int width;
5607 LONG stride;
5609 stride_tests[] =
5611 { &MFVideoFormat_RGB8, 3, -4 },
5612 { &MFVideoFormat_RGB8, 1, -4 },
5613 { &MFVideoFormat_RGB555, 3, -8 },
5614 { &MFVideoFormat_RGB555, 1, -4 },
5615 { &MFVideoFormat_RGB565, 3, -8 },
5616 { &MFVideoFormat_RGB565, 1, -4 },
5617 { &MFVideoFormat_RGB24, 3, -12 },
5618 { &MFVideoFormat_RGB24, 1, -4 },
5619 { &MFVideoFormat_RGB32, 3, -12 },
5620 { &MFVideoFormat_RGB32, 1, -4 },
5621 { &MFVideoFormat_ARGB32, 3, -12 },
5622 { &MFVideoFormat_ARGB32, 1, -4 },
5623 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5624 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5625 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5626 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5628 /* YUV */
5629 { &MFVideoFormat_NV12, 1, 1 },
5630 { &MFVideoFormat_NV12, 2, 2 },
5631 { &MFVideoFormat_NV12, 3, 3 },
5632 { &MFVideoFormat_AYUV, 1, 4 },
5633 { &MFVideoFormat_AYUV, 4, 16 },
5634 { &MFVideoFormat_AYUV, 5, 20 },
5635 { &MFVideoFormat_IMC1, 1, 4 },
5636 { &MFVideoFormat_IMC1, 2, 4 },
5637 { &MFVideoFormat_IMC1, 3, 8 },
5638 { &MFVideoFormat_IMC3, 1, 4 },
5639 { &MFVideoFormat_IMC3, 2, 4 },
5640 { &MFVideoFormat_IMC3, 3, 8 },
5641 { &MFVideoFormat_IMC2, 1, 1 },
5642 { &MFVideoFormat_IMC2, 2, 2 },
5643 { &MFVideoFormat_IMC2, 3, 3 },
5644 { &MFVideoFormat_IMC4, 1, 1 },
5645 { &MFVideoFormat_IMC4, 2, 2 },
5646 { &MFVideoFormat_IMC4, 3, 3 },
5647 { &MFVideoFormat_YV12, 1, 1 },
5648 { &MFVideoFormat_YV12, 2, 2 },
5649 { &MFVideoFormat_YV12, 3, 3 },
5650 { &MFVideoFormat_YV12, 320, 320 },
5651 { &MFVideoFormat_I420, 1, 1 },
5652 { &MFVideoFormat_I420, 2, 2 },
5653 { &MFVideoFormat_I420, 3, 3 },
5654 { &MFVideoFormat_I420, 320, 320 },
5655 { &MFVideoFormat_IYUV, 1, 1 },
5656 { &MFVideoFormat_IYUV, 2, 2 },
5657 { &MFVideoFormat_IYUV, 3, 3 },
5658 { &MFVideoFormat_IYUV, 320, 320 },
5660 unsigned int i;
5661 LONG stride;
5662 HRESULT hr;
5664 if (!pMFGetStrideForBitmapInfoHeader)
5666 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5667 return;
5670 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5671 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5673 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5675 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5676 ok(hr == S_OK, "%u: failed to get stride, hr %#lx.\n", i, hr);
5677 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %ld, expected %ld.\n", i,
5678 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5682 static void test_MFCreate2DMediaBuffer(void)
5684 static const struct _2d_buffer_test
5686 unsigned int width;
5687 unsigned int height;
5688 unsigned int fourcc;
5689 unsigned int contiguous_length;
5690 int pitch;
5691 unsigned int plane_multiplier;
5692 unsigned int max_length;
5693 } _2d_buffer_tests[] =
5695 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64, 0, 192 },
5696 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5697 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5698 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5699 { 4, 16, MAKEFOURCC('N','V','1','2'), 96, 64, 0, 1536 },
5701 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128, 0, 384 },
5702 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5703 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5704 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5705 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5706 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5708 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128, 2 },
5709 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128, 2 },
5710 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 2, 4096 },
5711 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128, 2 },
5713 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128, 2 },
5714 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128, 2 },
5715 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 2, 4096 },
5716 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128, 2 },
5718 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5719 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5720 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128, 0, 3072 },
5722 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5723 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5724 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64, 0, 1024 },
5726 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5727 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5728 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64, 0, 1024 },
5730 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5731 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5732 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64, 0, 1024 },
5734 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5735 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5736 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5738 static const char two_aas[] = { 0xaa, 0xaa };
5739 static const char eight_bbs[] = { 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb };
5740 DWORD max_length, length, length2;
5741 BYTE *buffer_start, *data, *data2;
5742 LONG pitch, pitch2, stride;
5743 IMF2DBuffer2 *_2dbuffer2;
5744 IMF2DBuffer *_2dbuffer;
5745 IMFMediaBuffer *buffer;
5746 int i, j, k;
5747 HRESULT hr;
5748 BOOL ret;
5750 if (!pMFCreate2DMediaBuffer)
5752 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5753 return;
5756 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5757 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5759 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5760 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5762 /* YUV formats can't be bottom-up. */
5763 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5764 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#lx.\n", hr);
5766 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5767 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5769 check_interface(buffer, &IID_IMFGetService, TRUE);
5770 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5772 /* Full backing buffer size, with 64 bytes per row alignment. */
5773 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5774 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5775 ok(max_length > 0, "Unexpected length %lu.\n", max_length);
5777 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5778 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5779 ok(!length, "Unexpected length.\n");
5781 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5782 ok(hr == S_OK, "Failed to set current length, hr %#lx.\n", hr);
5784 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5785 ok(hr == S_OK, "Failed to get current length, hr %#lx.\n", hr);
5786 ok(length == 10, "Unexpected length.\n");
5788 /* Linear lock/unlock. */
5790 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5791 ok(FAILED(hr), "Unexpected hr %#lx.\n", hr);
5793 /* Linear locking call returns plane size.*/
5794 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5795 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5796 ok(max_length == length, "Unexpected length.\n");
5798 memset(data, 0xaa, length);
5800 length = 0;
5801 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5802 ok(max_length == length && length == 9, "Unexpected length %lu.\n", length);
5804 /* Already locked */
5805 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5806 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5807 ok(data2 == data, "Unexpected pointer.\n");
5809 hr = IMFMediaBuffer_Unlock(buffer);
5810 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5812 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5813 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
5815 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5816 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5818 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5819 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5820 ok(length == 9, "Unexpected length %lu.\n", length);
5822 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5823 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5825 /* 2D lock. */
5826 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5827 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#lx.\n", hr);
5829 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5830 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5832 hr = IMFMediaBuffer_Unlock(buffer);
5833 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5835 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5836 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5838 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5839 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5841 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5842 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5844 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5845 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5847 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5848 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5849 ok(!!data, "Expected data pointer.\n");
5850 ok(pitch == 64, "Unexpected pitch %ld.\n", pitch);
5852 for (i = 0; i < 4; i++)
5853 ok(memcmp(&data[64 * i], two_aas, sizeof(two_aas)) == 0, "Invalid data instead of 0xaa.\n");
5854 memset(data, 0xbb, 194);
5856 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5857 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5858 ok(data == data2, "Expected data pointer.\n");
5860 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5861 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5863 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5864 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5866 /* Active 2D lock */
5867 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5868 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5870 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5871 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5873 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5874 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
5876 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5877 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5879 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5880 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
5882 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5883 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5885 ok(memcmp(data, eight_bbs, sizeof(eight_bbs)) == 0, "Invalid data instead of 0xbb.\n");
5887 hr = IMFMediaBuffer_Unlock(buffer);
5888 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5890 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5891 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#lx.\n", hr);
5893 if (SUCCEEDED(hr))
5895 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5896 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5898 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5899 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5901 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5902 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5904 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5905 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5907 /* Flags are ignored. */
5908 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5909 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5911 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5912 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5914 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5915 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5917 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5918 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5920 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5921 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5923 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5924 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
5926 IMF2DBuffer2_Release(_2dbuffer2);
5928 else
5929 win_skip("IMF2DBuffer2 is not supported.\n");
5931 IMF2DBuffer_Release(_2dbuffer);
5933 IMFMediaBuffer_Release(buffer);
5935 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5937 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5939 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5940 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
5942 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5943 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
5944 if (ptr->max_length)
5945 ok(length == ptr->max_length, "%u: unexpected maximum length %lu for %u x %u, format %s.\n",
5946 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5948 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5949 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
5951 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5952 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
5953 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %lu for %u x %u, format %s.\n",
5954 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5956 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5957 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5958 ok(length2 == ptr->contiguous_length, "%d: unexpected linear buffer length %lu for %u x %u, format %s.\n",
5959 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5961 memset(data, 0xff, length2);
5963 hr = IMFMediaBuffer_Unlock(buffer);
5964 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
5966 hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2);
5967 ok(hr == S_OK, "Failed to get plane size, hr %#lx.\n", hr);
5968 if (ptr->plane_multiplier)
5969 length2 *= ptr->plane_multiplier;
5970 ok(length2 == length, "%d: contiguous length %lu does not match plane size %lu, %u x %u, format %s.\n", i, length,
5971 length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5973 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5974 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
5976 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
5977 ok(hr == S_OK, "Failed to get scanline, hr %#lx.\n", hr);
5978 ok(data2 == data, "Unexpected data pointer.\n");
5979 ok(pitch == pitch2, "Unexpected pitch.\n");
5981 /* primary plane */
5982 for(j = 0; j < ptr->height; j++)
5983 for (k = 0; k < ptr->width; k++)
5984 ok(data[j * pitch + k] == 0xff, "Unexpected byte %02x at test %d row %d column %d.\n", data[j * pitch + k], i, j, k);
5986 hr = pMFGetStrideForBitmapInfoHeader(ptr->fourcc, ptr->width, &stride);
5987 ok(hr == S_OK, "Failed to get stride, hr %#lx.\n", hr);
5989 /* secondary planes */
5990 switch (ptr->fourcc)
5992 case MAKEFOURCC('I','M','C','1'):
5993 case MAKEFOURCC('I','M','C','3'):
5994 for (j = ptr->height; j < length2 / stride; j++)
5995 for (k = 0; k < ptr->width / 2; k++)
5996 ok(data[j * pitch + k] == 0xff, "Unexpected byte %02x at test %d row %d column %d.\n", data[j * pitch + k], i, j, k);
5997 break;
5999 case MAKEFOURCC('I','M','C','2'):
6000 case MAKEFOURCC('I','M','C','4'):
6001 for (j = ptr->height; j < length2 / stride; j++)
6002 for (k = 0; k < ptr->width / 2; k++)
6003 ok(data[j * pitch + k] == 0xff, "Unexpected byte %02x at test %d row %d column %d.\n", data[j * pitch + k], i, j, k);
6004 for (j = ptr->height; j < length2 / stride; j++)
6005 for (k = pitch / 2; k < pitch / 2 + ptr->width / 2; k++)
6006 ok(data[j * pitch + k] == 0xff, "Unexpected byte %02x at test %d row %d column %d.\n", data[j * pitch + k], i, j, k);
6007 break;
6009 case MAKEFOURCC('N','V','1','2'):
6010 for (j = ptr->height; j < length2 / stride; j++)
6011 for (k = 0; k < ptr->width; k++)
6012 ok(data[j * pitch + k] == 0xff, "Unexpected byte %02x at test %d row %d column %d.\n", data[j * pitch + k], i, j, k);
6013 break;
6015 default:
6019 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6020 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6022 ok(pitch == ptr->pitch, "%d: unexpected pitch %ld, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
6023 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
6025 ret = TRUE;
6026 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
6027 ok(hr == S_OK, "Failed to get format flag, hr %#lx.\n", hr);
6028 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
6030 IMF2DBuffer_Release(_2dbuffer);
6032 IMFMediaBuffer_Release(buffer);
6035 /* Alignment tests */
6036 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
6038 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
6040 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
6041 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6043 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6044 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6046 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6047 ok(hr == S_OK, "Failed to lock buffer, hr %#lx.\n", hr);
6048 ok(((uintptr_t)data & MF_64_BYTE_ALIGNMENT) == 0, "Misaligned data at %p.\n", data);
6050 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6051 ok(hr == S_OK, "Failed to unlock buffer, hr %#lx.\n", hr);
6053 IMF2DBuffer_Release(_2dbuffer);
6054 IMFMediaBuffer_Release(buffer);
6058 static void test_MFCreateMediaBufferFromMediaType(void)
6060 static struct audio_buffer_test
6062 unsigned int duration;
6063 unsigned int min_length;
6064 unsigned int min_alignment;
6065 unsigned int block_alignment;
6066 unsigned int bytes_per_second;
6067 unsigned int buffer_length;
6068 } audio_tests[] =
6070 { 0, 0, 0, 4, 0, 20 },
6071 { 0, 16, 0, 4, 0, 20 },
6072 { 0, 0, 32, 4, 0, 36 },
6073 { 0, 64, 32, 4, 0, 64 },
6074 { 1, 0, 0, 4, 16, 36 },
6075 { 2, 0, 0, 4, 16, 52 },
6076 { 2, 0, 64, 4, 16, 68 },
6077 { 2, 0, 128, 4, 16,132 },
6079 IMFMediaType *media_type, *media_type2;
6080 unsigned int i, alignment;
6081 IMFMediaBuffer *buffer;
6082 DWORD length, max;
6083 BYTE *data;
6084 HRESULT hr;
6086 if (!pMFCreateMediaBufferFromMediaType)
6088 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
6089 return;
6092 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
6093 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6095 hr = MFCreateMediaType(&media_type);
6096 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6098 hr = MFCreateMediaType(&media_type2);
6099 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6101 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
6102 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6104 hr = IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)media_type2);
6105 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6107 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
6109 const struct audio_buffer_test *ptr = &audio_tests[i];
6111 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
6112 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6114 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
6115 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
6117 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
6118 ptr->min_alignment, &buffer);
6119 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#lx.\n", hr);
6120 if (FAILED(hr))
6121 break;
6123 check_interface(buffer, &IID_IMFGetService, FALSE);
6125 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6126 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6127 ok(ptr->buffer_length == length, "%d: unexpected buffer length %lu, expected %u.\n", i, length, ptr->buffer_length);
6129 alignment = ptr->min_alignment ? ptr->min_alignment - 1 : MF_16_BYTE_ALIGNMENT;
6130 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6131 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6132 ok(ptr->buffer_length == max && !length, "Unexpected length.\n");
6133 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6134 hr = IMFMediaBuffer_Unlock(buffer);
6135 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6137 IMFMediaBuffer_Release(buffer);
6139 /* Only major type is set. */
6140 hr = pMFCreateMediaBufferFromMediaType(media_type2, ptr->duration * 10000000, ptr->min_length,
6141 ptr->min_alignment, &buffer);
6142 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6144 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
6145 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6146 ok(ptr->min_length == length, "%u: unexpected buffer length %lu, expected %u.\n", i, length, ptr->min_length);
6148 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
6149 ok(hr == S_OK, "Failed to lock, hr %#lx.\n", hr);
6150 ok(ptr->min_length == max && !length, "Unexpected length.\n");
6151 ok(!((uintptr_t)data & alignment), "%u: data at %p is misaligned.\n", i, data);
6152 hr = IMFMediaBuffer_Unlock(buffer);
6153 ok(hr == S_OK, "Failed to unlock, hr %#lx.\n", hr);
6155 IMFMediaBuffer_Release(buffer);
6158 IMFMediaType_Release(media_type);
6159 IMFMediaType_Release(media_type2);
6162 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
6164 GUID guid, subtype;
6165 UINT32 value;
6166 HRESULT hr;
6168 hr = IMFMediaType_GetMajorType(mediatype, &guid);
6169 ok(hr == S_OK, "Failed to get major type, hr %#lx.\n", hr);
6170 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
6172 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
6173 ok(hr == S_OK, "Failed to get subtype, hr %#lx.\n", hr);
6175 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
6177 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
6178 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6180 if (fex->dwChannelMask)
6182 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
6183 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6184 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
6187 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
6189 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
6190 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6191 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
6194 else
6196 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
6197 subtype.Data1 = format->wFormatTag;
6198 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
6200 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
6201 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6202 ok(value, "Unexpected value.\n");
6205 if (format->nChannels)
6207 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
6208 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6209 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
6212 if (format->nSamplesPerSec)
6214 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
6215 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6216 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
6219 if (format->nAvgBytesPerSec)
6221 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
6222 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6223 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
6226 if (format->nBlockAlign)
6228 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
6229 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6230 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
6233 if (format->wBitsPerSample)
6235 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
6236 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6237 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
6240 /* Only set for uncompressed formats. */
6241 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
6242 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
6243 IsEqualGUID(&guid, &MFAudioFormat_PCM))
6245 ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr);
6246 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
6248 else
6249 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
6252 static void test_MFInitMediaTypeFromWaveFormatEx(void)
6254 static const WAVEFORMATEX waveformatex_tests[] =
6256 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
6257 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
6258 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
6259 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
6260 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
6261 { 1234, 0, 0, 0, 0, 0 },
6262 { WAVE_FORMAT_ALAW },
6263 { WAVE_FORMAT_CREATIVE_ADPCM },
6264 { WAVE_FORMAT_MPEGLAYER3 },
6265 { WAVE_FORMAT_MPEG_ADTS_AAC },
6266 { WAVE_FORMAT_ALAC },
6267 { WAVE_FORMAT_AMR_NB },
6268 { WAVE_FORMAT_AMR_WB },
6269 { WAVE_FORMAT_AMR_WP },
6270 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
6271 { WAVE_FORMAT_DRM },
6272 { WAVE_FORMAT_DTS },
6273 { WAVE_FORMAT_FLAC },
6274 { WAVE_FORMAT_MPEG },
6275 { WAVE_FORMAT_WMAVOICE9 },
6276 { WAVE_FORMAT_OPUS },
6277 { WAVE_FORMAT_WMAUDIO2 },
6278 { WAVE_FORMAT_WMAUDIO3 },
6279 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
6280 { WAVE_FORMAT_WMASPDIF },
6283 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
6284 WAVEFORMATEXTENSIBLE waveformatext;
6285 MPEGLAYER3WAVEFORMAT mp3format;
6286 IMFMediaType *mediatype;
6287 unsigned int i, size;
6288 HRESULT hr;
6290 hr = MFCreateMediaType(&mediatype);
6291 ok(hr == S_OK, "Failed to create mediatype, hr %#lx.\n", hr);
6293 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
6295 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
6296 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#lx.\n", i, waveformatex_tests[i].wFormatTag, hr);
6298 validate_media_type(mediatype, &waveformatex_tests[i]);
6300 waveformatext.Format = waveformatex_tests[i];
6301 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
6302 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
6303 waveformatext.Samples.wSamplesPerBlock = 123;
6304 waveformatext.dwChannelMask = 0x8;
6305 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
6306 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
6308 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
6309 ok(hr == S_OK, "Failed to initialize media type, hr %#lx.\n", hr);
6311 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
6312 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
6314 validate_media_type(mediatype, &waveformatext.Format);
6317 /* MPEGLAYER3WAVEFORMAT */
6318 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
6319 mp3format.wfx.nChannels = 2;
6320 mp3format.wfx.nSamplesPerSec = 44100;
6321 mp3format.wfx.nAvgBytesPerSec = 16000;
6322 mp3format.wfx.nBlockAlign = 1;
6323 mp3format.wfx.wBitsPerSample = 0;
6324 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
6325 mp3format.wID = MPEGLAYER3_ID_MPEG;
6326 mp3format.fdwFlags = 0;
6327 mp3format.nBlockSize = 417;
6328 mp3format.nFramesPerBlock = 0;
6329 mp3format.nCodecDelay = 0;
6331 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
6332 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6334 validate_media_type(mediatype, &mp3format.wfx);
6335 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
6336 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6337 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
6338 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
6340 IMFMediaType_Release(mediatype);
6343 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
6345 MFVIDEOFORMAT *video_format;
6346 IMFMediaType *media_type;
6347 UINT32 size;
6348 HRESULT hr;
6350 hr = MFCreateMediaType(&media_type);
6351 ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
6353 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
6354 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6355 ok(!!video_format, "Unexpected format.\n");
6356 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
6357 CoTaskMemFree(video_format);
6359 IMFMediaType_Release(media_type);
6362 static void test_MFCreateDXSurfaceBuffer(void)
6364 IDirect3DSurface9 *backbuffer = NULL, *surface;
6365 IDirect3DSwapChain9 *swapchain;
6366 DWORD length, max_length;
6367 IDirect3DDevice9 *device;
6368 IMF2DBuffer2 *_2dbuffer2;
6369 IMFMediaBuffer *buffer;
6370 IMF2DBuffer *_2dbuffer;
6371 BYTE *data, *data2;
6372 IMFGetService *gs;
6373 IDirect3D9 *d3d;
6374 HWND window;
6375 HRESULT hr;
6376 LONG pitch;
6377 BOOL value;
6379 if (!pMFCreateDXSurfaceBuffer)
6381 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
6382 return;
6385 window = create_window();
6386 d3d = Direct3DCreate9(D3D_SDK_VERSION);
6387 ok(!!d3d, "Failed to create a D3D object.\n");
6388 if (!(device = create_d3d9_device(d3d, window)))
6390 skip("Failed to create a D3D device, skipping tests.\n");
6391 goto done;
6394 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
6395 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08lx)\n", hr);
6397 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
6398 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08lx)\n", hr);
6399 ok(backbuffer != NULL, "The back buffer is NULL\n");
6401 IDirect3DSwapChain9_Release(swapchain);
6403 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
6404 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
6406 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
6407 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6409 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6410 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6411 check_interface(buffer, &IID_IMFGetService, TRUE);
6413 /* Surface is accessible. */
6414 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
6415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6416 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
6417 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6418 ok(surface == backbuffer, "Unexpected surface pointer.\n");
6419 IDirect3DSurface9_Release(surface);
6420 IMFGetService_Release(gs);
6422 max_length = 0;
6423 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6424 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6425 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6427 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6428 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6429 ok(!length, "Unexpected length %lu.\n", length);
6431 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6432 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6434 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
6435 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6436 ok(length == 2 * max_length, "Unexpected length %lu.\n", length);
6438 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
6439 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6440 ok(length == max_length, "Unexpected length.\n");
6442 /* Unlock twice. */
6443 hr = IMFMediaBuffer_Unlock(buffer);
6444 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6446 hr = IMFMediaBuffer_Unlock(buffer);
6447 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6449 /* Lock twice. */
6450 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6451 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6453 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6454 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6455 ok(data == data2, "Unexpected pointer.\n");
6457 hr = IMFMediaBuffer_Unlock(buffer);
6458 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6460 hr = IMFMediaBuffer_Unlock(buffer);
6461 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6463 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
6464 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6466 /* Unlocked. */
6467 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6468 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6470 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6471 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6473 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6474 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6476 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6477 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
6479 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6480 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6482 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6483 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6485 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6486 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6488 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6489 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
6491 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6492 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6493 ok(!value, "Unexpected return value %d.\n", value);
6495 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6496 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6497 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6498 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6499 ok(length == max_length, "Unexpected length %lu.\n", length);
6501 IMF2DBuffer_Release(_2dbuffer);
6503 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6504 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6506 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6507 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6508 ok(data == data2, "Unexpected scanline pointer.\n");
6509 memset(data, 0xab, 4);
6510 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6512 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6513 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6514 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6515 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6517 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6518 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6519 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6520 hr = IMFMediaBuffer_Unlock(buffer);
6521 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6523 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6524 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6525 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6527 IMF2DBuffer2_Release(_2dbuffer2);
6529 IMFMediaBuffer_Release(buffer);
6531 done:
6532 if (backbuffer)
6533 IDirect3DSurface9_Release(backbuffer);
6534 IDirect3D9_Release(d3d);
6535 DestroyWindow(window);
6538 static void test_MFCreateTrackedSample(void)
6540 IMFTrackedSample *tracked_sample;
6541 IMFSample *sample;
6542 IUnknown *unk;
6543 HRESULT hr;
6545 if (!pMFCreateTrackedSample)
6547 win_skip("MFCreateTrackedSample() is not available.\n");
6548 return;
6551 hr = pMFCreateTrackedSample(&tracked_sample);
6552 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6554 /* It's actually a sample. */
6555 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6556 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6558 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6559 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6560 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6561 IUnknown_Release(unk);
6563 IMFSample_Release(sample);
6565 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6567 IMFTrackedSample_Release(tracked_sample);
6570 static void test_MFFrameRateToAverageTimePerFrame(void)
6572 static const struct frame_rate_test
6574 unsigned int numerator;
6575 unsigned int denominator;
6576 UINT64 avgtime;
6577 } frame_rate_tests[] =
6579 { 60000, 1001, 166833 },
6580 { 30000, 1001, 333667 },
6581 { 24000, 1001, 417188 },
6582 { 60, 1, 166667 },
6583 { 30, 1, 333333 },
6584 { 50, 1, 200000 },
6585 { 25, 1, 400000 },
6586 { 24, 1, 416667 },
6588 { 39, 1, 256410 },
6589 { 120, 1, 83333 },
6591 unsigned int i;
6592 UINT64 avgtime;
6593 HRESULT hr;
6595 avgtime = 1;
6596 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6597 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6598 ok(!avgtime, "Unexpected frame time.\n");
6600 avgtime = 1;
6601 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6602 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6603 ok(!avgtime, "Unexpected frame time.\n");
6605 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6607 avgtime = 0;
6608 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6609 frame_rate_tests[i].denominator, &avgtime);
6610 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6611 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6612 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6616 static void test_MFAverageTimePerFrameToFrameRate(void)
6618 static const struct frame_rate_test
6620 unsigned int numerator;
6621 unsigned int denominator;
6622 UINT64 avgtime;
6623 } frame_rate_tests[] =
6625 { 60000, 1001, 166833 },
6626 { 30000, 1001, 333667 },
6627 { 24000, 1001, 417188 },
6628 { 60, 1, 166667 },
6629 { 30, 1, 333333 },
6630 { 50, 1, 200000 },
6631 { 25, 1, 400000 },
6632 { 24, 1, 416667 },
6634 { 1000000, 25641, 256410 },
6635 { 10000000, 83333, 83333 },
6636 { 1, 10, 100000000 },
6637 { 1, 10, 100000001 },
6638 { 1, 10, 200000000 },
6639 { 1, 1, 10000000 },
6640 { 1, 2, 20000000 },
6641 { 5, 1, 2000000 },
6642 { 10, 1, 1000000 },
6644 unsigned int i, numerator, denominator;
6645 HRESULT hr;
6647 numerator = denominator = 1;
6648 hr = MFAverageTimePerFrameToFrameRate(0, &numerator, &denominator);
6649 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6650 ok(!numerator && !denominator, "Unexpected output %u/%u.\n", numerator, denominator);
6652 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6654 numerator = denominator = 12345;
6655 hr = MFAverageTimePerFrameToFrameRate(frame_rate_tests[i].avgtime, &numerator, &denominator);
6656 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6657 ok(numerator == frame_rate_tests[i].numerator && denominator == frame_rate_tests[i].denominator,
6658 "%u: unexpected %u/%u, expected %u/%u.\n", i, numerator, denominator, frame_rate_tests[i].numerator,
6659 frame_rate_tests[i].denominator);
6663 static void test_MFMapDXGIFormatToDX9Format(void)
6665 static const struct format_pair
6667 DXGI_FORMAT dxgi_format;
6668 DWORD d3d9_format;
6670 formats_map[] =
6672 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6673 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6674 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6675 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6676 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6677 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6678 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6679 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6680 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6681 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6682 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6683 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6684 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6685 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6686 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6687 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6688 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6689 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6690 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6691 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6692 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6693 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6694 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6695 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6696 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6697 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6698 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6699 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6700 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6701 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6702 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6703 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6704 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6705 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6706 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6707 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6708 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6709 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6710 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6711 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6712 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6713 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6714 { DXGI_FORMAT_P8, D3DFMT_P8 },
6715 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6717 unsigned int i;
6718 DWORD format;
6720 if (!pMFMapDXGIFormatToDX9Format)
6722 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6723 return;
6726 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6728 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6729 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#lx, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6733 static void test_MFMapDX9FormatToDXGIFormat(void)
6735 static const struct format_pair
6737 DXGI_FORMAT dxgi_format;
6738 DWORD d3d9_format;
6740 formats_map[] =
6742 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6743 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6744 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6745 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6746 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6747 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6748 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6749 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6750 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6751 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6752 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6753 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6754 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6755 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6756 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6757 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6758 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6759 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6760 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6761 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6762 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6763 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6764 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6765 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6766 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6767 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6768 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6769 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6770 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6771 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6772 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6773 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6774 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6775 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6776 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6777 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6778 { DXGI_FORMAT_P8, D3DFMT_P8 },
6779 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6781 DXGI_FORMAT format;
6782 unsigned int i;
6784 if (!pMFMapDX9FormatToDXGIFormat)
6786 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6787 return;
6790 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6792 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6793 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#lx.\n",
6794 format, formats_map[i].d3d9_format);
6798 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6799 REFIID riid, void **obj)
6801 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6802 IsEqualIID(riid, &IID_IUnknown))
6804 *obj = iface;
6805 IMFVideoSampleAllocatorNotify_AddRef(iface);
6806 return S_OK;
6809 *obj = NULL;
6810 return E_NOINTERFACE;
6813 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6815 return 2;
6818 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6820 return 1;
6823 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6825 return E_NOTIMPL;
6828 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6830 test_notify_callback_QueryInterface,
6831 test_notify_callback_AddRef,
6832 test_notify_callback_Release,
6833 test_notify_callback_NotifyRelease,
6836 static IMFMediaType * create_video_type(const GUID *subtype)
6838 IMFMediaType *video_type;
6839 HRESULT hr;
6841 hr = MFCreateMediaType(&video_type);
6842 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6844 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6845 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6847 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6848 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6850 return video_type;
6853 static ID3D11Device *create_d3d11_device(void)
6855 static const D3D_FEATURE_LEVEL default_feature_level[] =
6857 D3D_FEATURE_LEVEL_11_0,
6858 D3D_FEATURE_LEVEL_10_1,
6859 D3D_FEATURE_LEVEL_10_0,
6861 const D3D_FEATURE_LEVEL *feature_level;
6862 unsigned int feature_level_count;
6863 ID3D11Device *device;
6865 feature_level = default_feature_level;
6866 feature_level_count = ARRAY_SIZE(default_feature_level);
6868 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6869 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6870 return device;
6871 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6872 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6873 return device;
6874 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6875 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6876 return device;
6878 return NULL;
6881 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
6882 const BYTE *data, unsigned int src_pitch)
6884 ID3D11DeviceContext *immediate_context;
6885 ID3D11Device *device;
6887 ID3D11Texture2D_GetDevice(texture, &device);
6888 ID3D11Device_GetImmediateContext(device, &immediate_context);
6890 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
6891 sub_resource_idx, NULL, data, src_pitch, 0);
6893 ID3D11DeviceContext_Release(immediate_context);
6894 ID3D11Device_Release(device);
6897 static ID3D12Device *create_d3d12_device(void)
6899 ID3D12Device *device;
6900 HRESULT hr;
6902 if (!pD3D12CreateDevice) return NULL;
6904 hr = pD3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, &IID_ID3D12Device, (void **)&device);
6905 if (FAILED(hr))
6906 return NULL;
6908 return device;
6911 static void test_d3d11_surface_buffer(void)
6913 DWORD max_length, cur_length, length, color;
6914 IMFDXGIBuffer *dxgi_buffer;
6915 D3D11_TEXTURE2D_DESC desc;
6916 ID3D11Texture2D *texture;
6917 IMF2DBuffer *_2d_buffer;
6918 IMFMediaBuffer *buffer;
6919 ID3D11Device *device;
6920 BYTE buff[64 * 64 * 4];
6921 BYTE *data, *data2;
6922 LONG pitch, pitch2;
6923 UINT index, size;
6924 IUnknown *obj;
6925 HRESULT hr;
6927 if (!pMFCreateDXGISurfaceBuffer)
6929 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
6930 return;
6933 /* d3d11 */
6934 if (!(device = create_d3d11_device()))
6936 skip("Failed to create a D3D11 device, skipping tests.\n");
6937 return;
6940 memset(&desc, 0, sizeof(desc));
6941 desc.Width = 64;
6942 desc.Height = 64;
6943 desc.ArraySize = 1;
6944 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
6945 desc.SampleDesc.Count = 1;
6946 desc.SampleDesc.Quality = 0;
6948 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6949 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
6951 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
6952 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
6954 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6955 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6956 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6957 check_interface(buffer, &IID_IMFGetService, FALSE);
6959 max_length = 0;
6960 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6961 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6962 ok(!!max_length, "Unexpected length %lu.\n", max_length);
6964 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6965 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6966 ok(!cur_length, "Unexpected length %lu.\n", cur_length);
6968 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6969 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6971 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6972 ok(hr == S_OK, "Failed to get length, hr %#lx.\n", hr);
6973 ok(cur_length == 2 * max_length, "Unexpected length %lu.\n", cur_length);
6975 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6976 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6978 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
6979 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6980 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
6981 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
6982 ok(length == max_length, "Unexpected length %lu.\n", length);
6983 IMF2DBuffer_Release(_2d_buffer);
6985 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6986 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
6988 EXPECT_REF(texture, 2);
6989 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
6990 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
6991 EXPECT_REF(texture, 3);
6992 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
6993 IUnknown_Release(obj);
6995 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
6996 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
6998 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
6999 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7000 ok(index == 0, "Unexpected subresource index.\n");
7002 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7003 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7005 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7006 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7008 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
7009 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#lx.\n", hr);
7011 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
7012 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7014 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
7015 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7016 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
7017 IUnknown_Release(obj);
7019 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
7020 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7022 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
7023 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
7025 IMFDXGIBuffer_Release(dxgi_buffer);
7027 /* Texture updates. */
7028 color = get_d3d11_texture_color(texture, 0, 0);
7029 ok(!color, "Unexpected texture color %#lx.\n", color);
7031 max_length = cur_length = 0;
7032 data = NULL;
7033 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7034 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7035 ok(max_length && max_length == cur_length, "Unexpected length %lu.\n", max_length);
7036 if (data) *(DWORD *)data = ~0u;
7038 color = get_d3d11_texture_color(texture, 0, 0);
7039 ok(!color, "Unexpected texture color %#lx.\n", color);
7041 hr = IMFMediaBuffer_Unlock(buffer);
7042 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7044 color = get_d3d11_texture_color(texture, 0, 0);
7045 ok(color == ~0u, "Unexpected texture color %#lx.\n", color);
7047 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7048 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7049 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#lx.\n", *(DWORD *)data);
7051 hr = IMFMediaBuffer_Unlock(buffer);
7052 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7054 /* Lock2D()/Unlock2D() */
7055 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7056 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7058 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7059 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7061 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7062 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7063 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7065 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7066 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7067 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7069 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7070 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7071 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7073 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
7074 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr);
7076 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7077 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7079 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7080 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7082 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7083 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#lx.\n", hr);
7085 IMF2DBuffer_Release(_2d_buffer);
7086 IMFMediaBuffer_Release(buffer);
7088 /* Bottom up. */
7089 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
7090 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7092 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7093 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7095 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7096 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7097 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7099 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
7100 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7101 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
7103 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7104 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7106 IMF2DBuffer_Release(_2d_buffer);
7107 IMFMediaBuffer_Release(buffer);
7109 ID3D11Texture2D_Release(texture);
7111 /* Subresource index 1. */
7112 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
7113 ok(hr == S_OK, "Failed to create a texture, hr %#lx.\n", hr);
7115 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
7116 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7118 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
7119 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7121 /* Pitch reflects top level. */
7122 memset(buff, 0, sizeof(buff));
7123 *(DWORD *)buff = 0xff00ff00;
7124 update_d3d11_texture(texture, 1, buff, 64 * 4);
7126 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
7127 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7128 ok(pitch == desc.Width * 4, "Unexpected pitch %ld.\n", pitch);
7129 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#lx.\n", *(DWORD *)data);
7131 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
7132 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7134 IMF2DBuffer_Release(_2d_buffer);
7135 IMFMediaBuffer_Release(buffer);
7137 ID3D11Texture2D_Release(texture);
7139 ID3D11Device_Release(device);
7142 static void test_d3d12_surface_buffer(void)
7144 IMFDXGIBuffer *dxgi_buffer;
7145 D3D12_HEAP_PROPERTIES heap_props;
7146 D3D12_RESOURCE_DESC desc;
7147 ID3D12Resource *resource;
7148 IMFMediaBuffer *buffer;
7149 unsigned int refcount;
7150 ID3D12Device *device;
7151 IUnknown *obj;
7152 HRESULT hr;
7154 /* d3d12 */
7155 if (!(device = create_d3d12_device()))
7157 skip("Failed to create a D3D12 device, skipping tests.\n");
7158 return;
7161 memset(&heap_props, 0, sizeof(heap_props));
7162 heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;
7164 memset(&desc, 0, sizeof(desc));
7165 desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
7166 desc.Alignment = 0;
7167 desc.Width = 32;
7168 desc.Height = 32;
7169 desc.DepthOrArraySize = 1;
7170 desc.MipLevels = 1;
7171 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
7172 desc.SampleDesc.Count = 1;
7173 desc.SampleDesc.Quality = 0;
7174 desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
7175 desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
7177 hr = ID3D12Device_CreateCommittedResource(device, &heap_props, D3D12_HEAP_FLAG_NONE,
7178 &desc, D3D12_RESOURCE_STATE_RENDER_TARGET, NULL, &IID_ID3D12Resource, (void **)&resource);
7179 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7181 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D12Resource, (IUnknown *)resource, 0, FALSE, &buffer);
7182 if (hr == E_INVALIDARG)
7184 todo_wine
7185 win_skip("D3D12 resource buffers are not supported.\n");
7186 goto notsupported;
7188 ok(hr == S_OK, "Failed to create a buffer, hr %#lx.\n", hr);
7190 if (SUCCEEDED(hr))
7192 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7193 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7194 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7195 check_interface(buffer, &IID_IMFGetService, FALSE);
7197 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7198 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7200 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&obj);
7201 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7202 ok(obj == (IUnknown *)resource, "Unexpected resource pointer.\n");
7203 IUnknown_Release(obj);
7205 IMFDXGIBuffer_Release(dxgi_buffer);
7206 IMFMediaBuffer_Release(buffer);
7209 notsupported:
7210 ID3D12Resource_Release(resource);
7211 refcount = ID3D12Device_Release(device);
7212 ok(!refcount, "Unexpected device refcount %u.\n", refcount);
7215 static void test_sample_allocator_sysmem(void)
7217 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
7218 IMFMediaType *media_type, *video_type, *video_type2;
7219 IMFVideoSampleAllocatorCallback *allocator_cb;
7220 IMFVideoSampleAllocatorEx *allocatorex;
7221 IMFVideoSampleAllocator *allocator;
7222 IMFSample *sample, *sample2;
7223 IMFAttributes *attributes;
7224 IMFMediaBuffer *buffer;
7225 LONG refcount, count;
7226 DWORD buffer_count;
7227 IUnknown *unk;
7228 HRESULT hr;
7230 if (!pMFCreateVideoSampleAllocatorEx)
7231 return;
7233 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
7234 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7236 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
7237 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
7238 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
7240 IUnknown_Release(unk);
7242 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7243 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7245 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7246 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7248 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7249 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7251 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
7252 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7254 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
7255 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7257 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
7258 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7260 count = 10;
7261 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7262 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7263 ok(!count, "Unexpected count %ld.\n", count);
7265 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7266 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7268 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7269 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7271 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
7272 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7274 hr = MFCreateMediaType(&media_type);
7275 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7277 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
7278 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7280 video_type = create_video_type(&MFVideoFormat_RGB32);
7281 video_type2 = create_video_type(&MFVideoFormat_RGB32);
7283 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7284 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
7286 /* Frame size is required. */
7287 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7288 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7290 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
7291 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7293 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
7294 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7296 EXPECT_REF(video_type, 1);
7297 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7298 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7299 EXPECT_REF(video_type, 2);
7301 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
7302 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7304 /* Setting identical type does not replace it. */
7305 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7306 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7307 EXPECT_REF(video_type, 2);
7308 EXPECT_REF(video_type2, 1);
7310 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7311 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7313 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
7314 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7315 EXPECT_REF(video_type2, 2);
7316 EXPECT_REF(video_type, 1);
7318 /* Modify referenced type. */
7319 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
7320 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7322 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7323 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7324 EXPECT_REF(video_type, 2);
7325 EXPECT_REF(video_type2, 1);
7327 count = 0;
7328 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7329 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7330 ok(count == 1, "Unexpected count %ld.\n", count);
7332 sample = NULL;
7333 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7334 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7335 refcount = get_refcount(sample);
7337 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7338 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7339 ok(!count, "Unexpected count %ld.\n", count);
7341 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
7342 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7344 /* Reinitialize with active sample. */
7345 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
7346 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7347 ok(refcount == get_refcount(sample), "Unexpected refcount %lu.\n", get_refcount(sample));
7348 EXPECT_REF(video_type, 2);
7350 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7351 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7352 todo_wine
7353 ok(!count, "Unexpected count %ld.\n", count);
7355 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7356 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7358 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7359 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7361 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7362 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7363 check_interface(buffer, &IID_IMFGetService, TRUE);
7364 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7366 IMFMediaBuffer_Release(buffer);
7368 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7369 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7370 ok(buffer_count == 1, "Unexpected buffer count %lu.\n", buffer_count);
7372 IMFSample_Release(sample);
7374 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
7375 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7376 todo_wine
7377 EXPECT_REF(video_type, 2);
7379 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7380 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7381 ok(!count, "Unexpected count %ld.\n", count);
7383 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7384 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7386 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7387 IMFVideoSampleAllocator_Release(allocator);
7389 /* IMFVideoSampleAllocatorEx */
7390 hr = MFCreateAttributes(&attributes, 0);
7391 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7393 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7394 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7396 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
7397 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7399 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
7400 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7402 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
7403 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7405 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7406 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#lx.\n", hr);
7408 EXPECT_REF(attributes, 1);
7409 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7410 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7411 EXPECT_REF(attributes, 2);
7413 count = 0;
7414 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
7415 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7416 ok(count == 1, "Unexpected count %ld.\n", count);
7418 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7419 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7421 hr = IMFSample_GetBufferCount(sample, &buffer_count);
7422 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7423 ok(buffer_count == 2, "Unexpected buffer count %lu.\n", buffer_count);
7425 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7426 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#lx.\n", hr);
7428 /* Reinitialize with already allocated samples. */
7429 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
7430 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7431 EXPECT_REF(attributes, 1);
7433 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
7434 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7435 IMFSample_Release(sample2);
7437 IMFSample_Release(sample);
7439 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
7440 IMFVideoSampleAllocatorEx_Release(allocatorex);
7441 IMFAttributes_Release(attributes);
7444 static void test_sample_allocator_d3d9(void)
7446 IDirect3DDeviceManager9 *d3d9_manager;
7447 IMFVideoSampleAllocator *allocator;
7448 IDirect3DDevice9 *d3d9_device;
7449 IMFMediaType *video_type;
7450 IMFMediaBuffer *buffer;
7451 unsigned int token;
7452 IMFSample *sample;
7453 IDirect3D9 *d3d9;
7454 HWND window;
7455 HRESULT hr;
7457 if (!pMFCreateVideoSampleAllocatorEx)
7458 return;
7460 window = create_window();
7461 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7462 ok(!!d3d9, "Failed to create a D3D9 object.\n");
7463 if (!(d3d9_device = create_d3d9_device(d3d9, window)))
7465 skip("Failed to create a D3D9 device, skipping tests.\n");
7466 goto done;
7469 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
7470 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7472 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
7473 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7475 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7476 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7478 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
7479 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7481 video_type = create_video_type(&MFVideoFormat_RGB32);
7483 /* Frame size is required. */
7484 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7485 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7487 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7488 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7490 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7491 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7493 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7494 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7496 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7497 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7499 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7500 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7501 check_interface(buffer, &IID_IMFGetService, TRUE);
7502 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7504 IMFSample_Release(sample);
7505 IMFMediaBuffer_Release(buffer);
7507 IMFVideoSampleAllocator_Release(allocator);
7508 IMFMediaType_Release(video_type);
7510 done:
7511 IDirect3D9_Release(d3d9);
7512 DestroyWindow(window);
7515 static void test_sample_allocator_d3d11(void)
7517 IMFMediaType *video_type;
7518 IMFVideoSampleAllocatorEx *allocatorex;
7519 IMFVideoSampleAllocator *allocator;
7520 unsigned int i, token;
7521 IMFDXGIDeviceManager *manager;
7522 IMFSample *sample;
7523 IMFDXGIBuffer *dxgi_buffer;
7524 IMFAttributes *attributes;
7525 D3D11_TEXTURE2D_DESC desc;
7526 ID3D11Texture2D *texture;
7527 IMFMediaBuffer *buffer;
7528 ID3D11Device *device;
7529 HRESULT hr;
7530 BYTE *data;
7531 static const unsigned int usage[] =
7533 D3D11_USAGE_DEFAULT,
7534 D3D11_USAGE_IMMUTABLE,
7535 D3D11_USAGE_DYNAMIC,
7536 D3D11_USAGE_STAGING,
7537 D3D11_USAGE_STAGING + 1,
7539 static const unsigned int sharing[] =
7541 D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7542 D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX,
7543 D3D11_RESOURCE_MISC_SHARED,
7546 if (!pMFCreateVideoSampleAllocatorEx)
7547 return;
7549 if (!(device = create_d3d11_device()))
7551 skip("Failed to create a D3D11 device, skipping tests.\n");
7552 return;
7555 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7556 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7558 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7559 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
7561 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7562 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7564 EXPECT_REF(manager, 1);
7565 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
7566 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7567 EXPECT_REF(manager, 2);
7569 video_type = create_video_type(&MFVideoFormat_RGB32);
7570 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7571 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7573 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7574 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7576 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7577 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7579 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7580 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7582 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7583 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7584 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7585 check_interface(buffer, &IID_IMFGetService, FALSE);
7587 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7588 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7590 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7591 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7593 ID3D11Texture2D_GetDesc(texture, &desc);
7594 ok(desc.Width == 64, "Unexpected width %u.\n", desc.Width);
7595 ok(desc.Height == 64, "Unexpected height %u.\n", desc.Height);
7596 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
7597 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
7598 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
7599 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
7600 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
7601 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
7602 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7603 desc.BindFlags);
7604 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7605 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7607 ID3D11Texture2D_Release(texture);
7608 IMFDXGIBuffer_Release(dxgi_buffer);
7610 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
7611 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7613 hr = IMFMediaBuffer_Unlock(buffer);
7614 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7616 IMFSample_Release(sample);
7618 IMFVideoSampleAllocator_Release(allocator);
7620 /* MF_SA_D3D11_USAGE */
7621 hr = MFCreateAttributes(&attributes, 1);
7622 ok(hr == S_OK, "Failed to create attributes, hr %#lx.\n", hr);
7624 for (i = 0; i < ARRAY_SIZE(usage); ++i)
7626 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7627 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7629 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7630 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7632 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
7633 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7635 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7636 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
7638 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7639 IMFVideoSampleAllocatorEx_Release(allocatorex);
7640 continue;
7642 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", usage[i], hr);
7644 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7645 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7647 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7648 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7650 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7651 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7653 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7654 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7656 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7657 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7659 ID3D11Texture2D_GetDesc(texture, &desc);
7660 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
7661 if (usage[i] == D3D11_USAGE_DEFAULT)
7663 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
7664 desc.BindFlags);
7665 ok(!desc.CPUAccessFlags, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7667 else if (usage[i] == D3D11_USAGE_DYNAMIC)
7669 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
7670 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
7672 else if (usage[i] == D3D11_USAGE_STAGING)
7674 ok(!desc.BindFlags, "Unexpected bind flags %#x.\n", desc.BindFlags);
7675 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
7676 desc.CPUAccessFlags);
7678 ok(!desc.MiscFlags, "Unexpected misc flags %#x.\n", desc.MiscFlags);
7680 ID3D11Texture2D_Release(texture);
7681 IMFDXGIBuffer_Release(dxgi_buffer);
7682 IMFMediaBuffer_Release(buffer);
7684 IMFSample_Release(sample);
7686 IMFVideoSampleAllocatorEx_Release(allocatorex);
7689 /* MF_SA_D3D11_SHARED, MF_SA_D3D11_SHARED_WITHOUT_MUTEX */
7690 for (i = 0; i < ARRAY_SIZE(sharing); ++i)
7692 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
7693 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7695 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
7696 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7698 hr = IMFAttributes_DeleteAllItems(attributes);
7699 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7701 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
7702 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7704 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX)
7706 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED, TRUE);
7707 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7710 if (sharing[i] & D3D11_RESOURCE_MISC_SHARED)
7712 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_SHARED_WITHOUT_MUTEX, TRUE);
7713 ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
7716 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
7717 if (sharing[i] == (D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED))
7719 todo_wine
7720 ok(hr == E_INVALIDARG, "%u: Unexpected hr %#lx.\n", i, hr);
7721 IMFVideoSampleAllocatorEx_Release(allocatorex);
7722 continue;
7724 ok(hr == S_OK, "%u: Unexpected hr %#lx.\n", i, hr);
7726 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
7727 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7729 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7730 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7732 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7733 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7735 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
7736 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7738 ID3D11Texture2D_GetDesc(texture, &desc);
7739 ok(desc.MiscFlags == sharing[i], "%u: unexpected misc flags %#x.\n", i, desc.MiscFlags);
7741 ID3D11Texture2D_Release(texture);
7742 IMFDXGIBuffer_Release(dxgi_buffer);
7743 IMFMediaBuffer_Release(buffer);
7745 IMFSample_Release(sample);
7747 IMFVideoSampleAllocatorEx_Release(allocatorex);
7750 IMFAttributes_Release(attributes);
7752 IMFDXGIDeviceManager_Release(manager);
7753 ID3D11Device_Release(device);
7756 static void test_sample_allocator_d3d12(void)
7758 IMFVideoSampleAllocator *allocator;
7759 D3D12_HEAP_PROPERTIES heap_props;
7760 IMFDXGIDeviceManager *manager;
7761 D3D12_HEAP_FLAGS heap_flags;
7762 IMFDXGIBuffer *dxgi_buffer;
7763 IMFMediaType *video_type;
7764 ID3D12Resource *resource;
7765 D3D12_RESOURCE_DESC desc;
7766 IMFMediaBuffer *buffer;
7767 ID3D12Device *device;
7768 unsigned int token;
7769 IMFSample *sample;
7770 HRESULT hr;
7772 if (!(device = create_d3d12_device()))
7774 skip("Failed to create a D3D12 device, skipping tests.\n");
7775 return;
7778 hr = pMFCreateDXGIDeviceManager(&token, &manager);
7779 ok(hr == S_OK, "Failed to create device manager, hr %#lx.\n", hr);
7781 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
7782 if (FAILED(hr))
7784 win_skip("Device manager does not support D3D12 devices.\n");
7785 goto done;
7787 ok(hr == S_OK, "Failed to set a device, hr %#lx.\n", hr);
7789 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7790 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7792 EXPECT_REF(manager, 1);
7793 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
7794 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7795 EXPECT_REF(manager, 2);
7797 video_type = create_video_type(&MFVideoFormat_RGB32);
7798 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
7799 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7800 hr = IMFMediaType_SetUINT32(video_type, &MF_MT_D3D_RESOURCE_VERSION, MF_D3D12_RESOURCE);
7801 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7803 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7804 todo_wine
7805 ok(hr == S_OK || broken(hr == MF_E_UNEXPECTED) /* Some Win10 versions fail. */, "Unexpected hr %#lx.\n", hr);
7806 if (FAILED(hr)) goto done;
7808 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7809 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7811 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7812 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7814 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7815 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7816 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
7817 check_interface(buffer, &IID_IMFGetService, FALSE);
7819 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
7820 ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr);
7822 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D12Resource, (void **)&resource);
7823 ok(hr == S_OK, "Failed to get resource, hr %#lx.\n", hr);
7825 resource->lpVtbl->GetDesc(resource, &desc);
7826 ok(desc.Width == 64, "Unexpected width.\n");
7827 ok(desc.Height == 64, "Unexpected height.\n");
7828 ok(desc.DepthOrArraySize == 1, "Unexpected array size %u.\n", desc.DepthOrArraySize);
7829 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
7830 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
7831 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
7832 ok(!desc.SampleDesc.Quality, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
7833 ok(!desc.Layout, "Unexpected layout %u.\n", desc.Layout);
7834 ok(!desc.Flags, "Unexpected flags %#x.\n", desc.Flags);
7836 hr = ID3D12Resource_GetHeapProperties(resource, &heap_props, &heap_flags);
7837 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7838 ok(heap_props.Type == D3D12_HEAP_TYPE_DEFAULT, "Unexpected heap type %u.\n", heap_props.Type);
7839 ok(heap_props.CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_UNKNOWN, "Unexpected page property %u.\n",
7840 heap_props.CPUPageProperty);
7841 ok(!heap_props.MemoryPoolPreference, "Unexpected pool preference %u.\n", heap_props.MemoryPoolPreference);
7842 ok(heap_flags == D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES, "Unexpected heap flags %#x.\n", heap_flags);
7844 ID3D12Resource_Release(resource);
7845 IMFDXGIBuffer_Release(dxgi_buffer);
7846 IMFSample_Release(sample);
7848 IMFVideoSampleAllocator_Release(allocator);
7850 done:
7851 IMFDXGIDeviceManager_Release(manager);
7852 ID3D12Device_Release(device);
7855 static void test_MFLockSharedWorkQueue(void)
7857 DWORD taskid, queue, queue2;
7858 HRESULT hr;
7860 if (!pMFLockSharedWorkQueue)
7862 win_skip("MFLockSharedWorkQueue() is not available.\n");
7863 return;
7866 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
7867 ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr);
7869 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
7870 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7872 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
7873 ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
7875 taskid = 0;
7876 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
7877 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
7879 queue = 0;
7880 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
7881 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
7883 queue2 = 0;
7884 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
7885 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7886 ok(queue == queue2, "Unexpected queue %#lx.\n", queue2);
7888 hr = MFUnlockWorkQueue(queue2);
7889 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7891 hr = MFUnlockWorkQueue(queue);
7892 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7894 hr = MFShutdown();
7895 ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr);
7898 static void test_MFllMulDiv(void)
7900 /* (a * b + d) / c */
7901 static const struct muldivtest
7903 LONGLONG a;
7904 LONGLONG b;
7905 LONGLONG c;
7906 LONGLONG d;
7907 LONGLONG result;
7909 muldivtests[] =
7911 { 0, 0, 0, 0, _I64_MAX },
7912 { 1000000, 1000000, 2, 0, 500000000000 },
7913 { _I64_MAX, 3, _I64_MAX, 0, 3 },
7914 { _I64_MAX, 3, _I64_MAX, 1, 3 },
7915 { -10000, 3, 100, 0, -300 },
7916 { 2, 0, 3, 5, 1 },
7917 { 2, 1, 1, -3, -1 },
7918 /* a * b product does not fit in uint64_t */
7919 { _I64_MAX, 4, 8, 0, _I64_MAX / 2 },
7920 /* Large a * b product, large denominator */
7921 { _I64_MAX, 4, 0x100000000, 0, 0x1ffffffff },
7923 unsigned int i;
7925 for (i = 0; i < ARRAY_SIZE(muldivtests); ++i)
7927 LONGLONG result;
7929 result = MFllMulDiv(muldivtests[i].a, muldivtests[i].b, muldivtests[i].c, muldivtests[i].d);
7930 ok(result == muldivtests[i].result, "%u: unexpected result %s, expected %s.\n", i,
7931 wine_dbgstr_longlong(result), wine_dbgstr_longlong(muldivtests[i].result));
7935 static void test_shared_dxgi_device_manager(void)
7937 IMFDXGIDeviceManager *manager;
7938 HRESULT hr;
7939 UINT token;
7941 if (!pMFLockDXGIDeviceManager)
7943 win_skip("Shared DXGI device manager is not supported.\n");
7944 return;
7947 hr = pMFUnlockDXGIDeviceManager();
7948 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7950 manager = NULL;
7951 hr = pMFLockDXGIDeviceManager(NULL, &manager);
7952 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7953 ok(!!manager, "Unexpected instance.\n");
7955 hr = pMFLockDXGIDeviceManager(&token, &manager);
7956 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7958 EXPECT_REF(manager, 3);
7960 hr = pMFUnlockDXGIDeviceManager();
7961 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7963 EXPECT_REF(manager, 2);
7965 hr = pMFUnlockDXGIDeviceManager();
7966 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
7969 static void check_video_format(const MFVIDEOFORMAT *format, unsigned int width, unsigned int height,
7970 DWORD d3dformat)
7972 unsigned int transfer_function;
7973 GUID guid;
7975 if (!d3dformat) d3dformat = D3DFMT_X8R8G8B8;
7977 switch (d3dformat)
7979 case D3DFMT_X8R8G8B8:
7980 case D3DFMT_R8G8B8:
7981 case D3DFMT_A8R8G8B8:
7982 case D3DFMT_R5G6B5:
7983 case D3DFMT_X1R5G5B5:
7984 case D3DFMT_A2B10G10R10:
7985 case D3DFMT_P8:
7986 transfer_function = MFVideoTransFunc_sRGB;
7987 break;
7988 default:
7989 transfer_function = MFVideoTransFunc_10;
7992 memcpy(&guid, &MFVideoFormat_Base, sizeof(guid));
7993 guid.Data1 = d3dformat;
7995 ok(format->dwSize == sizeof(*format), "Unexpected format size.\n");
7996 ok(format->videoInfo.dwWidth == width, "Unexpected width %lu.\n", format->videoInfo.dwWidth);
7997 ok(format->videoInfo.dwHeight == height, "Unexpected height %lu.\n", format->videoInfo.dwHeight);
7998 ok(format->videoInfo.PixelAspectRatio.Numerator == 1 &&
7999 format->videoInfo.PixelAspectRatio.Denominator == 1, "Unexpected PAR.\n");
8000 ok(format->videoInfo.SourceChromaSubsampling == MFVideoChromaSubsampling_Unknown, "Unexpected chroma subsampling.\n");
8001 ok(format->videoInfo.InterlaceMode == MFVideoInterlace_Progressive, "Unexpected interlace mode %u.\n",
8002 format->videoInfo.InterlaceMode);
8003 ok(format->videoInfo.TransferFunction == transfer_function, "Unexpected transfer function %u.\n",
8004 format->videoInfo.TransferFunction);
8005 ok(format->videoInfo.ColorPrimaries == MFVideoPrimaries_BT709, "Unexpected color primaries %u.\n",
8006 format->videoInfo.ColorPrimaries);
8007 ok(format->videoInfo.TransferMatrix == MFVideoTransferMatrix_Unknown, "Unexpected transfer matrix.\n");
8008 ok(format->videoInfo.SourceLighting == MFVideoLighting_office, "Unexpected source lighting %u.\n",
8009 format->videoInfo.SourceLighting);
8010 ok(format->videoInfo.FramesPerSecond.Numerator == 60 &&
8011 format->videoInfo.FramesPerSecond.Denominator == 1, "Unexpected frame rate %lu/%lu.\n",
8012 format->videoInfo.FramesPerSecond.Numerator, format->videoInfo.FramesPerSecond.Denominator);
8013 ok(format->videoInfo.NominalRange == MFNominalRange_Normal, "Unexpected nominal range %u.\n",
8014 format->videoInfo.NominalRange);
8015 ok(format->videoInfo.GeometricAperture.Area.cx == width && format->videoInfo.GeometricAperture.Area.cy == height,
8016 "Unexpected geometric aperture.\n");
8017 ok(!memcmp(&format->videoInfo.GeometricAperture, &format->videoInfo.MinimumDisplayAperture, sizeof(MFVideoArea)),
8018 "Unexpected minimum display aperture.\n");
8019 ok(format->videoInfo.PanScanAperture.Area.cx == 0 && format->videoInfo.PanScanAperture.Area.cy == 0,
8020 "Unexpected geometric aperture.\n");
8021 ok(format->videoInfo.VideoFlags == 0, "Unexpected video flags.\n");
8022 ok(IsEqualGUID(&format->guidFormat, &guid), "Unexpected format guid %s.\n", wine_dbgstr_guid(&format->guidFormat));
8023 ok(format->compressedInfo.AvgBitrate == 0, "Unexpected bitrate.\n");
8024 ok(format->compressedInfo.AvgBitErrorRate == 0, "Unexpected error bitrate.\n");
8025 ok(format->compressedInfo.MaxKeyFrameSpacing == 0, "Unexpected MaxKeyFrameSpacing.\n");
8026 ok(format->surfaceInfo.Format == d3dformat, "Unexpected format %lu.\n", format->surfaceInfo.Format);
8027 ok(format->surfaceInfo.PaletteEntries == 0, "Unexpected palette size %lu.\n", format->surfaceInfo.PaletteEntries);
8030 static void test_MFInitVideoFormat_RGB(void)
8032 static const DWORD formats[] =
8034 0, /* same D3DFMT_X8R8G8B8 */
8035 D3DFMT_X8R8G8B8,
8036 D3DFMT_R8G8B8,
8037 D3DFMT_A8R8G8B8,
8038 D3DFMT_R5G6B5,
8039 D3DFMT_X1R5G5B5,
8040 D3DFMT_A2B10G10R10,
8041 D3DFMT_P8,
8042 D3DFMT_L8,
8043 D3DFMT_YUY2,
8044 D3DFMT_DXT1,
8045 D3DFMT_D16,
8046 D3DFMT_L16,
8047 D3DFMT_A16B16G16R16F,
8049 MFVIDEOFORMAT format;
8050 unsigned int i;
8051 HRESULT hr;
8053 if (!pMFInitVideoFormat_RGB)
8055 win_skip("MFInitVideoFormat_RGB is not available.\n");
8056 return;
8059 hr = pMFInitVideoFormat_RGB(NULL, 64, 32, 0);
8060 ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
8062 for (i = 0; i < ARRAY_SIZE(formats); ++i)
8064 memset(&format, 0, sizeof(format));
8065 hr = pMFInitVideoFormat_RGB(&format, 64, 32, formats[i]);
8066 ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
8067 if (SUCCEEDED(hr))
8068 check_video_format(&format, 64, 32, formats[i]);
8072 START_TEST(mfplat)
8074 char **argv;
8075 int argc;
8077 init_functions();
8079 argc = winetest_get_mainargs(&argv);
8080 if (argc >= 3)
8082 test_queue_com_state(argv[2]);
8083 return;
8086 if (!pMFCreateVideoSampleAllocatorEx)
8087 win_skip("MFCreateVideoSampleAllocatorEx() is not available. Some tests will be skipped.\n");
8089 if (!pD3D12CreateDevice)
8090 skip("Missing d3d12 support, some tests will be skipped.\n");
8092 CoInitialize(NULL);
8094 test_startup();
8095 test_register();
8096 test_media_type();
8097 test_MFCreateMediaEvent();
8098 test_attributes();
8099 test_sample();
8100 test_file_stream();
8101 test_MFCreateMFByteStreamOnStream();
8102 test_system_memory_buffer();
8103 test_system_memory_aligned_buffer();
8104 test_source_resolver();
8105 test_MFCreateAsyncResult();
8106 test_allocate_queue();
8107 test_MFLockSharedWorkQueue();
8108 test_MFCopyImage();
8109 test_MFCreateCollection();
8110 test_MFHeapAlloc();
8111 test_scheduled_items();
8112 test_serial_queue();
8113 test_periodic_callback();
8114 test_event_queue();
8115 test_presentation_descriptor();
8116 test_system_time_source();
8117 test_MFInvokeCallback();
8118 test_stream_descriptor();
8119 test_MFCalculateImageSize();
8120 test_MFGetPlaneSize();
8121 test_MFCompareFullToPartialMediaType();
8122 test_attributes_serialization();
8123 test_wrapped_media_type();
8124 test_MFCreateWaveFormatExFromMFMediaType();
8125 test_async_create_file();
8126 test_local_handlers();
8127 test_create_property_store();
8128 test_dxgi_device_manager();
8129 test_MFCreateTransformActivate();
8130 test_MFTRegisterLocal();
8131 test_queue_com();
8132 test_MFGetStrideForBitmapInfoHeader();
8133 test_MFCreate2DMediaBuffer();
8134 test_MFCreateMediaBufferFromMediaType();
8135 test_MFInitMediaTypeFromWaveFormatEx();
8136 test_MFCreateMFVideoFormatFromMFMediaType();
8137 test_MFCreateDXSurfaceBuffer();
8138 test_MFCreateTrackedSample();
8139 test_MFFrameRateToAverageTimePerFrame();
8140 test_MFAverageTimePerFrameToFrameRate();
8141 test_MFMapDXGIFormatToDX9Format();
8142 test_d3d11_surface_buffer();
8143 test_d3d12_surface_buffer();
8144 test_sample_allocator_sysmem();
8145 test_sample_allocator_d3d9();
8146 test_sample_allocator_d3d11();
8147 test_sample_allocator_d3d12();
8148 test_MFMapDX9FormatToDXGIFormat();
8149 test_MFllMulDiv();
8150 test_shared_dxgi_device_manager();
8151 test_MFInitVideoFormat_RGB();
8153 CoUninitialize();