mfplat: Implement GetContiguousLength() for d3d11 buffer.
[wine/zf.git] / dlls / mfplat / tests / mfplat.c
blobaa6c0e28da6ca842a98c75595ad8b1e294e19203
1 /*
2 * Unit test suite for mfplat.
4 * Copyright 2015 Michael Müller
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
22 #include <string.h>
24 #define COBJMACROS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winuser.h"
29 #include "winreg.h"
30 #include "ole2.h"
31 #include "mfapi.h"
32 #include "mfidl.h"
33 #include "mferror.h"
34 #include "mfreadwrite.h"
35 #include "propvarutil.h"
36 #include "strsafe.h"
37 #include "evr.h"
39 #include "wine/test.h"
40 #include "wine/heap.h"
42 #define D3D11_INIT_GUID
43 #include "initguid.h"
44 #include "d3d11_4.h"
45 #include "d3d9.h"
46 #include "d3d9types.h"
47 #include "ks.h"
48 #include "ksmedia.h"
49 #include "dxva2api.h"
51 DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19);
52 DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21);
53 DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22);
54 DEFINE_GUID(DUMMY_GUID3, 0x12345678,0x1234,0x1234,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23);
56 extern const CLSID CLSID_FileSchemePlugin;
58 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1'));
59 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2'));
60 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3'));
61 DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4'));
63 static BOOL is_win8_plus;
65 #define EXPECT_REF(obj,ref) _expect_ref((IUnknown*)obj, ref, __LINE__)
66 static void _expect_ref(IUnknown *obj, ULONG ref, int line)
68 ULONG rc;
69 IUnknown_AddRef(obj);
70 rc = IUnknown_Release(obj);
71 ok_(__FILE__,line)(rc == ref, "Unexpected refcount %d, expected %d.\n", rc, ref);
74 static ULONG get_refcount(void *iface)
76 IUnknown *unknown = iface;
77 IUnknown_AddRef(unknown);
78 return IUnknown_Release(unknown);
81 #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
82 static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
84 IUnknown *iface = iface_ptr;
85 HRESULT hr, expected_hr;
86 IUnknown *unk;
88 expected_hr = supported ? S_OK : E_NOINTERFACE;
90 hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
91 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
92 if (SUCCEEDED(hr))
93 IUnknown_Release(unk);
96 struct d3d11_resource_readback
98 ID3D11Resource *resource;
99 D3D11_MAPPED_SUBRESOURCE map_desc;
100 ID3D11DeviceContext *immediate_context;
101 unsigned int width, height, depth, sub_resource_idx;
104 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
105 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
106 ID3D11Device *device, struct d3d11_resource_readback *rb)
108 HRESULT hr;
110 rb->resource = readback_resource;
111 rb->width = width;
112 rb->height = height;
113 rb->depth = depth;
114 rb->sub_resource_idx = sub_resource_idx;
116 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
118 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
119 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
120 rb->resource, sub_resource_idx, D3D11_MAP_READ, 0, &rb->map_desc)))
122 trace("Failed to map resource, hr %#x.\n", hr);
123 ID3D11Resource_Release(rb->resource);
124 rb->resource = NULL;
125 ID3D11DeviceContext_Release(rb->immediate_context);
126 rb->immediate_context = NULL;
130 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
131 struct d3d11_resource_readback *rb)
133 D3D11_TEXTURE2D_DESC texture_desc;
134 ID3D11Resource *rb_texture;
135 unsigned int miplevel;
136 ID3D11Device *device;
137 HRESULT hr;
139 memset(rb, 0, sizeof(*rb));
141 ID3D11Texture2D_GetDevice(texture, &device);
143 ID3D11Texture2D_GetDesc(texture, &texture_desc);
144 texture_desc.Usage = D3D11_USAGE_STAGING;
145 texture_desc.BindFlags = 0;
146 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
147 texture_desc.MiscFlags = 0;
148 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
150 trace("Failed to create texture, hr %#x.\n", hr);
151 ID3D11Device_Release(device);
152 return;
155 miplevel = sub_resource_idx % texture_desc.MipLevels;
156 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
157 max(1, texture_desc.Width >> miplevel),
158 max(1, texture_desc.Height >> miplevel),
159 1, sub_resource_idx, device, rb);
161 ID3D11Device_Release(device);
164 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb)
166 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
167 ID3D11Resource_Release(rb->resource);
168 ID3D11DeviceContext_Release(rb->immediate_context);
171 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
172 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
174 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
177 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
179 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
182 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
184 return get_d3d11_readback_u32(rb, x, y, z);
187 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
189 struct d3d11_resource_readback rb;
190 DWORD color;
192 get_d3d11_texture2d_readback(texture, 0, &rb);
193 color = get_d3d11_readback_color(&rb, x, y, 0);
194 release_d3d11_resource_readback(&rb);
196 return color;
199 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
200 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
201 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
203 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
205 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
206 DWORD width, DWORD lines);
207 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
208 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
209 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
210 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
211 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
212 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
213 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
214 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
215 IMFActivate *activate);
216 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
217 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
218 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
219 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
220 const MFT_REGISTER_TYPE_INFO* output_types);
221 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
222 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
223 const MFT_REGISTER_TYPE_INFO *output_types);
224 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
225 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
226 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
227 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
228 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
229 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
230 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
231 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
232 IMFMediaBuffer **buffer);
233 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
234 DWORD min_alignment, IMFMediaBuffer **buffer);
235 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
236 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
237 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
238 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
239 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
240 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
241 IMFMediaBuffer **buffer);
242 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
244 static HWND create_window(void)
246 RECT r = {0, 0, 640, 480};
248 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
250 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
251 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
254 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
256 D3DPRESENT_PARAMETERS present_parameters = {0};
257 IDirect3DDevice9 *device = NULL;
259 present_parameters.BackBufferWidth = 640;
260 present_parameters.BackBufferHeight = 480;
261 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
262 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
263 present_parameters.hDeviceWindow = focus_window;
264 present_parameters.Windowed = TRUE;
265 present_parameters.EnableAutoDepthStencil = TRUE;
266 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
267 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
269 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
270 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
272 return device;
275 static const WCHAR fileschemeW[] = L"file://";
277 static WCHAR *load_resource(const WCHAR *name)
279 static WCHAR pathW[MAX_PATH];
280 DWORD written;
281 HANDLE file;
282 HRSRC res;
283 void *ptr;
285 GetTempPathW(ARRAY_SIZE(pathW), pathW);
286 lstrcatW(pathW, name);
288 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
289 NULL, CREATE_ALWAYS, 0, 0);
290 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
291 wine_dbgstr_w(pathW), GetLastError());
293 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
294 ok(res != 0, "couldn't find resource\n");
295 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
296 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
297 &written, NULL);
298 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
299 "couldn't write resource\n" );
300 CloseHandle(file);
302 return pathW;
305 struct test_callback
307 IMFAsyncCallback IMFAsyncCallback_iface;
308 HANDLE event;
309 DWORD param;
310 IMFMediaEvent *media_event;
313 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
315 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
318 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
320 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
321 IsEqualIID(riid, &IID_IUnknown))
323 *obj = iface;
324 IMFAsyncCallback_AddRef(iface);
325 return S_OK;
328 *obj = NULL;
329 return E_NOINTERFACE;
332 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
334 return 2;
337 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
339 return 1;
342 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
344 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
345 return E_NOTIMPL;
349 static BOOL check_clsid(CLSID *clsids, UINT32 count)
351 int i;
352 for (i = 0; i < count; i++)
354 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
355 return TRUE;
357 return FALSE;
360 static void test_register(void)
362 WCHAR name[] = L"Wine test";
363 MFT_REGISTER_TYPE_INFO input[] =
365 { DUMMY_CLSID, DUMMY_GUID1 }
367 MFT_REGISTER_TYPE_INFO output[] =
369 { DUMMY_CLSID, DUMMY_GUID2 }
371 CLSID *clsids;
372 UINT32 count;
373 HRESULT ret;
375 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
376 if (ret == E_ACCESSDENIED)
378 win_skip("Not enough permissions to register a filter\n");
379 return;
381 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
383 if(0)
385 /* NULL name crashes on windows */
386 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
387 ok(ret == E_INVALIDARG, "got %x\n", ret);
390 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
391 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
393 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
394 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
396 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
397 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
399 if(0)
401 /* NULL clsids/count crashes on windows (vista) */
402 count = 0;
403 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
404 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
405 ok(count == 0, "Expected count == 0\n");
407 clsids = NULL;
408 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
409 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
412 count = 0;
413 clsids = NULL;
414 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
415 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
416 ok(count > 0, "Expected count > 0\n");
417 ok(clsids != NULL, "Expected clsids != NULL\n");
418 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
419 CoTaskMemFree(clsids);
421 count = 0;
422 clsids = NULL;
423 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
424 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
425 ok(count > 0, "Expected count > 0\n");
426 ok(clsids != NULL, "Expected clsids != NULL\n");
427 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
428 CoTaskMemFree(clsids);
430 count = 0;
431 clsids = NULL;
432 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
433 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
434 ok(count > 0, "Expected count > 0\n");
435 ok(clsids != NULL, "Expected clsids != NULL\n");
436 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
437 CoTaskMemFree(clsids);
439 count = 0;
440 clsids = NULL;
441 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
442 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
443 ok(count > 0, "Expected count > 0\n");
444 ok(clsids != NULL, "Expected clsids != NULL\n");
445 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
446 CoTaskMemFree(clsids);
448 /* exchange input and output */
449 count = 0;
450 clsids = NULL;
451 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
452 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
453 ok(!count, "got %d\n", count);
454 ok(clsids == NULL, "Expected clsids == NULL\n");
456 ret = MFTUnregister(DUMMY_CLSID);
457 ok(ret == S_OK ||
458 /* w7pro64 */
459 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
461 ret = MFTUnregister(DUMMY_CLSID);
462 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
465 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
467 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
468 IMFSourceResolver *resolver;
469 IUnknown *object, *object2;
470 MF_OBJECT_TYPE obj_type;
471 HRESULT hr;
473 ok(!!result, "Unexpected result object.\n");
475 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
477 object = NULL;
478 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
479 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
481 hr = IMFAsyncResult_GetObject(result, &object2);
482 ok(hr == S_OK, "Failed to get result object, hr %#x.\n", hr);
483 ok(object2 == object, "Unexpected object.\n");
485 if (object)
486 IUnknown_Release(object);
487 IUnknown_Release(object2);
489 SetEvent(callback->event);
491 return S_OK;
494 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
496 testcallback_QueryInterface,
497 testcallback_AddRef,
498 testcallback_Release,
499 testcallback_GetParameters,
500 test_create_from_url_callback_Invoke,
503 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
505 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
506 IMFSchemeHandler *handler;
507 IUnknown *object, *object2;
508 MF_OBJECT_TYPE obj_type;
509 HRESULT hr;
511 ok(!!result, "Unexpected result object.\n");
513 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
515 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
516 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
518 if (SUCCEEDED(hr))
520 hr = IMFAsyncResult_GetObject(result, &object2);
521 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
523 IUnknown_Release(object);
526 SetEvent(callback->event);
528 return S_OK;
531 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
533 testcallback_QueryInterface,
534 testcallback_AddRef,
535 testcallback_Release,
536 testcallback_GetParameters,
537 test_create_from_file_handler_callback_Invoke,
540 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
542 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
543 IMFMediaEventGenerator *generator;
544 HRESULT hr;
546 ok(!!result, "Unexpected result object.\n");
548 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
550 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
551 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
553 SetEvent(callback->event);
555 return S_OK;
558 static const IMFAsyncCallbackVtbl events_callback_vtbl =
560 testcallback_QueryInterface,
561 testcallback_AddRef,
562 testcallback_Release,
563 testcallback_GetParameters,
564 source_events_callback_Invoke,
567 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
569 struct test_callback callback = {{ 0 }};
570 MediaEventType event_type;
571 BOOL ret = FALSE;
572 HRESULT hr;
574 callback.IMFAsyncCallback_iface.lpVtbl = &events_callback_vtbl;
575 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
577 for (;;)
579 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback.IMFAsyncCallback_iface,
580 (IUnknown *)generator);
581 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
583 if (WaitForSingleObject(callback.event, 1000) == WAIT_TIMEOUT)
585 ok(0, "timeout\n");
586 break;
589 Sleep(10);
591 hr = IMFMediaEvent_GetType(callback.media_event, &event_type);
592 ok(hr == S_OK, "Failed to event type, hr %#x.\n", hr);
594 if ((ret = (event_type == expected_event_type)))
596 if (value)
598 hr = IMFMediaEvent_GetValue(callback.media_event, value);
599 ok(hr == S_OK, "Failed to get value of event, hr %#x.\n", hr);
602 break;
606 CloseHandle(callback.event);
607 if (callback.media_event)
608 IMFMediaEvent_Release(callback.media_event);
610 return ret;
613 static void test_source_resolver(void)
615 struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
616 struct test_callback callback2 = { { &test_create_from_file_handler_callback_vtbl } };
617 IMFSourceResolver *resolver, *resolver2;
618 IMFPresentationDescriptor *descriptor;
619 IMFSchemeHandler *scheme_handler;
620 IMFMediaStream *video_stream;
621 IMFAttributes *attributes;
622 IMFMediaSource *mediasource;
623 IMFMediaTypeHandler *handler;
624 IMFMediaType *media_type;
625 BOOL selected, do_uninit;
626 MF_OBJECT_TYPE obj_type;
627 IMFStreamDescriptor *sd;
628 IUnknown *cancel_cookie;
629 IMFByteStream *stream;
630 WCHAR pathW[MAX_PATH];
631 int i, sample_count;
632 WCHAR *filename;
633 PROPVARIANT var;
634 HRESULT hr;
635 GUID guid;
637 if (!pMFCreateSourceResolver)
639 win_skip("MFCreateSourceResolver() not found\n");
640 return;
643 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
644 ok(hr == S_OK, "got 0x%08x\n", hr);
646 hr = pMFCreateSourceResolver(NULL);
647 ok(hr == E_POINTER, "got %#x\n", hr);
649 hr = pMFCreateSourceResolver(&resolver);
650 ok(hr == S_OK, "got %#x\n", hr);
652 hr = pMFCreateSourceResolver(&resolver2);
653 ok(hr == S_OK, "got %#x\n", hr);
654 ok(resolver != resolver2, "Expected new instance\n");
656 IMFSourceResolver_Release(resolver2);
658 filename = load_resource(L"test.mp4");
660 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
661 ok(hr == S_OK, "got 0x%08x\n", hr);
663 hr = IMFSourceResolver_CreateObjectFromByteStream(
664 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
665 &obj_type, (IUnknown **)&mediasource);
666 ok(hr == E_POINTER, "got 0x%08x\n", hr);
668 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
669 NULL, (IUnknown **)&mediasource);
670 ok(hr == E_POINTER, "got 0x%08x\n", hr);
672 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
673 &obj_type, NULL);
674 ok(hr == E_POINTER, "got 0x%08x\n", hr);
676 IMFByteStream_Release(stream);
678 /* Create from URL. */
679 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
681 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
682 (IUnknown **)&stream);
683 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#x.\n", hr);
685 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
686 (IUnknown **)&stream);
687 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
688 IMFByteStream_Release(stream);
690 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
691 &cancel_cookie, &callback.IMFAsyncCallback_iface, (IUnknown *)resolver);
692 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
693 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
694 IUnknown_Release(cancel_cookie);
696 if (SUCCEEDED(hr))
697 WaitForSingleObject(callback.event, INFINITE);
699 /* With explicit scheme. */
700 lstrcpyW(pathW, fileschemeW);
701 lstrcatW(pathW, filename);
703 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
704 (IUnknown **)&stream);
705 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
706 IMFByteStream_Release(stream);
708 /* We have to create a new bytestream here, because all following
709 * calls to CreateObjectFromByteStream will fail. */
710 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
711 ok(hr == S_OK, "got 0x%08x\n", hr);
713 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
714 ok(hr == S_OK, "got 0x%08x\n", hr);
715 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
716 ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr);
717 IMFAttributes_Release(attributes);
719 /* Start of gstreamer dependent tests */
721 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
722 &obj_type, (IUnknown **)&mediasource);
723 if (strcmp(winetest_platform, "wine"))
724 ok(hr == S_OK, "got 0x%08x\n", hr);
725 if (FAILED(hr))
727 IMFByteStream_Release(stream);
728 IMFSourceResolver_Release(resolver);
730 hr = MFShutdown();
731 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
733 DeleteFileW(filename);
734 return;
736 ok(mediasource != NULL, "got %p\n", mediasource);
737 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
739 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
740 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
741 ok(descriptor != NULL, "got %p\n", descriptor);
743 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
744 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
746 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
747 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
748 IMFStreamDescriptor_Release(sd);
750 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
751 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
753 /* Check major/minor type for the test media. */
754 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
756 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
757 ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
758 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
759 ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
760 todo_wine
761 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
762 IMFMediaType_Release(media_type);
764 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
765 ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr);
767 var.vt = VT_EMPTY;
768 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
769 ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
771 video_stream = NULL;
772 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
774 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
775 video_stream = (IMFMediaStream *)var.punkVal;
778 sample_count = 10;
780 for (i = 0; i < sample_count; ++i)
782 hr = IMFMediaStream_RequestSample(video_stream, NULL);
783 if (i == sample_count)
784 break;
785 ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
786 if (hr != S_OK)
787 break;
790 for (i = 0; i < sample_count; ++i)
792 static const LONGLONG MILLI_TO_100_NANO = 10000;
793 LONGLONG duration, time;
794 DWORD buffer_count;
795 IMFSample *sample;
796 BOOL ret;
798 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
799 ok(ret, "Sample %u not received.\n", i + 1);
800 if (!ret)
801 break;
803 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
804 sample = (IMFSample *)var.punkVal;
806 hr = IMFSample_GetBufferCount(sample, &buffer_count);
807 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
808 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
810 hr = IMFSample_GetSampleDuration(sample, &duration);
811 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
812 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
814 hr = IMFSample_GetSampleTime(sample, &time);
815 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
816 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
818 IMFSample_Release(sample);
821 if (i == sample_count)
823 IMFMediaEvent *event;
825 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
826 Sleep(100);
827 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
828 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
830 hr = IMFMediaStream_RequestSample(video_stream, NULL);
831 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
832 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
836 hr = IMFMediaStream_RequestSample(video_stream, NULL);
837 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
839 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
841 IMFMediaStream_Release(video_stream);
842 IMFMediaTypeHandler_Release(handler);
843 IMFPresentationDescriptor_Release(descriptor);
845 hr = IMFMediaSource_Shutdown(mediasource);
846 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
848 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
849 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
851 IMFMediaSource_Release(mediasource);
852 IMFByteStream_Release(stream);
854 /* Create directly through scheme handler. */
855 hr = CoInitialize(NULL);
856 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
857 do_uninit = hr == S_OK;
859 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
860 (void **)&scheme_handler);
861 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
863 callback2.event = callback.event;
864 cancel_cookie = NULL;
865 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
866 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
867 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
868 ok(!!cancel_cookie, "Unexpected cancel object.\n");
869 IUnknown_Release(cancel_cookie);
871 WaitForSingleObject(callback2.event, INFINITE);
873 IMFSchemeHandler_Release(scheme_handler);
875 if (do_uninit)
876 CoUninitialize();
878 CloseHandle(callback.event);
880 IMFSourceResolver_Release(resolver);
882 hr = MFShutdown();
883 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
885 DeleteFileW(filename);
888 static void init_functions(void)
890 HMODULE mod = GetModuleHandleA("mfplat.dll");
892 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
893 X(MFAddPeriodicCallback);
894 X(MFAllocateSerialWorkQueue);
895 X(MFAllocateWorkQueueEx);
896 X(MFCopyImage);
897 X(MFCreate2DMediaBuffer);
898 X(MFCreateDXGIDeviceManager);
899 X(MFCreateDXGISurfaceBuffer);
900 X(MFCreateDXSurfaceBuffer);
901 X(MFCreateSourceResolver);
902 X(MFCreateMediaBufferFromMediaType);
903 X(MFCreateMFByteStreamOnStream);
904 X(MFCreateTrackedSample);
905 X(MFCreateTransformActivate);
906 X(MFCreateVideoMediaTypeFromSubtype);
907 X(MFCreateVideoSampleAllocatorEx);
908 X(MFGetPlaneSize);
909 X(MFGetStrideForBitmapInfoHeader);
910 X(MFMapDX9FormatToDXGIFormat);
911 X(MFMapDXGIFormatToDX9Format);
912 X(MFPutWaitingWorkItem);
913 X(MFRegisterLocalByteStreamHandler);
914 X(MFRegisterLocalSchemeHandler);
915 X(MFRemovePeriodicCallback);
916 X(MFTEnumEx);
917 X(MFTRegisterLocal);
918 X(MFTRegisterLocalByCLSID);
919 X(MFTUnregisterLocal);
920 X(MFTUnregisterLocalByCLSID);
922 if ((mod = LoadLibraryA("d3d11.dll")))
924 X(D3D11CreateDevice);
927 mod = GetModuleHandleA("ole32.dll");
929 X(CoGetApartmentType);
930 #undef X
932 is_win8_plus = pMFPutWaitingWorkItem != NULL;
935 static void test_media_type(void)
937 IMFMediaType *mediatype, *mediatype2;
938 IMFVideoMediaType *video_type;
939 IUnknown *unk, *unk2;
940 DWORD count, flags;
941 BOOL compressed;
942 HRESULT hr;
943 GUID guid;
945 if(0)
947 /* Crash on Windows Vista/7 */
948 hr = MFCreateMediaType(NULL);
949 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
952 hr = MFCreateMediaType(&mediatype);
953 ok(hr == S_OK, "got 0x%08x\n", hr);
955 hr = IMFMediaType_GetMajorType(mediatype, &guid);
956 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
958 compressed = FALSE;
959 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
960 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
961 ok(compressed, "Unexpected value %d.\n", compressed);
963 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
964 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
966 compressed = FALSE;
967 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
968 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
969 ok(compressed, "Unexpected value %d.\n", compressed);
971 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
972 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
974 compressed = TRUE;
975 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
976 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
977 ok(!compressed, "Unexpected value %d.\n", compressed);
979 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
980 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
982 hr = IMFMediaType_GetMajorType(mediatype, &guid);
983 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
984 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
986 /* IsEqual() */
987 hr = MFCreateMediaType(&mediatype2);
988 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
990 flags = 0xdeadbeef;
991 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
992 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
993 ok(flags == 0, "Unexpected flags %#x.\n", flags);
995 /* Different major types. */
996 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
997 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
999 flags = 0;
1000 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1001 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1002 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1003 "Unexpected flags %#x.\n", flags);
1005 /* Same major types, different subtypes. */
1006 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1007 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
1009 flags = 0;
1010 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1011 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1012 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1013 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
1015 /* Different user data. */
1016 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1017 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1019 flags = 0;
1020 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1021 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1022 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1023 "Unexpected flags %#x.\n", flags);
1025 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1026 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1028 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1029 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
1031 flags = 0;
1032 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1033 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1034 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1035 "Unexpected flags %#x.\n", flags);
1037 IMFMediaType_Release(mediatype2);
1038 IMFMediaType_Release(mediatype);
1040 /* IMFVideoMediaType */
1041 hr = MFCreateMediaType(&mediatype);
1042 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1044 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1046 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1047 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1048 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1049 IUnknown_Release(unk);
1051 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1052 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1054 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1055 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1057 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1058 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1059 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1060 IUnknown_Release(unk2);
1062 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1063 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1064 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1065 IUnknown_Release(unk2);
1067 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1068 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1069 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1070 IUnknown_Release(unk2);
1072 IUnknown_Release(unk);
1073 IMFMediaType_Release(mediatype);
1075 if (pMFCreateVideoMediaTypeFromSubtype)
1077 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1078 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1080 check_interface(video_type, &IID_IMFMediaType, TRUE);
1081 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1083 /* Major and subtype are set on creation. */
1084 hr = IMFVideoMediaType_GetCount(video_type, &count);
1085 ok(count == 2, "Unexpected attribute count %#x.\n", hr);
1087 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1088 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1090 hr = IMFVideoMediaType_GetCount(video_type, &count);
1091 ok(!count, "Unexpected attribute count %#x.\n", hr);
1093 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1095 IMFVideoMediaType_Release(video_type);
1097 else
1098 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1100 /* IMFAudioMediaType */
1101 hr = MFCreateMediaType(&mediatype);
1102 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1104 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1106 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1107 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1108 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1109 IUnknown_Release(unk);
1111 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1112 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1114 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1115 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1117 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1118 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1119 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1120 IUnknown_Release(unk2);
1122 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1123 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1124 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1125 IUnknown_Release(unk2);
1127 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1128 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1129 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1130 IUnknown_Release(unk2);
1132 IUnknown_Release(unk);
1134 IMFMediaType_Release(mediatype);
1137 static void test_MFCreateMediaEvent(void)
1139 HRESULT hr;
1140 IMFMediaEvent *mediaevent;
1142 MediaEventType type;
1143 GUID extended_type;
1144 HRESULT status;
1145 PROPVARIANT value;
1147 PropVariantInit(&value);
1148 value.vt = VT_UNKNOWN;
1150 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1151 ok(hr == S_OK, "got 0x%08x\n", hr);
1153 PropVariantClear(&value);
1155 hr = IMFMediaEvent_GetType(mediaevent, &type);
1156 ok(hr == S_OK, "got 0x%08x\n", hr);
1157 ok(type == MEError, "got %#x\n", type);
1159 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1160 ok(hr == S_OK, "got 0x%08x\n", hr);
1161 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1162 wine_dbgstr_guid(&extended_type));
1164 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1165 ok(hr == S_OK, "got 0x%08x\n", hr);
1166 ok(status == E_FAIL, "got 0x%08x\n", status);
1168 PropVariantInit(&value);
1169 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1170 ok(hr == S_OK, "got 0x%08x\n", hr);
1171 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1172 PropVariantClear(&value);
1174 IMFMediaEvent_Release(mediaevent);
1176 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1177 ok(hr == S_OK, "got 0x%08x\n", hr);
1179 hr = IMFMediaEvent_GetType(mediaevent, &type);
1180 ok(hr == S_OK, "got 0x%08x\n", hr);
1181 ok(type == MEUnknown, "got %#x\n", type);
1183 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1184 ok(hr == S_OK, "got 0x%08x\n", hr);
1185 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1186 wine_dbgstr_guid(&extended_type));
1188 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1189 ok(hr == S_OK, "got 0x%08x\n", hr);
1190 ok(status == S_OK, "got 0x%08x\n", status);
1192 PropVariantInit(&value);
1193 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1194 ok(hr == S_OK, "got 0x%08x\n", hr);
1195 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1196 PropVariantClear(&value);
1198 IMFMediaEvent_Release(mediaevent);
1201 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1202 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1204 UINT32 count = expected + 1;
1205 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1206 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1207 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1210 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1211 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1213 MF_ATTRIBUTE_TYPE type;
1214 HRESULT hr;
1216 hr = IMFAttributes_GetItemType(obj, key, &type);
1217 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1218 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1221 static void test_attributes(void)
1223 static const WCHAR stringW[] = L"Wine";
1224 static const UINT8 blob[] = {0,1,2,3,4,5};
1225 IMFAttributes *attributes, *attributes1;
1226 UINT8 blob_value[256], *blob_buf = NULL;
1227 MF_ATTRIBUTES_MATCH_TYPE match_type;
1228 UINT32 value, string_length, size;
1229 PROPVARIANT propvar, ret_propvar;
1230 MF_ATTRIBUTE_TYPE type;
1231 double double_value;
1232 IUnknown *unk_value;
1233 WCHAR bufferW[256];
1234 UINT64 value64;
1235 WCHAR *string;
1236 BOOL result;
1237 HRESULT hr;
1238 GUID key;
1240 hr = MFCreateAttributes( &attributes, 3 );
1241 ok(hr == S_OK, "got 0x%08x\n", hr);
1243 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1244 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1246 CHECK_ATTR_COUNT(attributes, 0);
1247 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1248 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
1249 CHECK_ATTR_COUNT(attributes, 1);
1250 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1252 value = 0xdeadbeef;
1253 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1254 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
1255 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1257 value64 = 0xdeadbeef;
1258 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1259 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1260 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1262 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1263 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
1264 CHECK_ATTR_COUNT(attributes, 1);
1265 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1267 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1268 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
1269 ok(value64 == 65536, "Unexpected value.\n");
1271 value = 0xdeadbeef;
1272 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1273 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1274 ok(value == 0xdeadbeef, "Unexpected value.\n");
1276 IMFAttributes_Release(attributes);
1278 hr = MFCreateAttributes(&attributes, 0);
1279 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1281 PropVariantInit(&propvar);
1282 propvar.vt = MF_ATTRIBUTE_UINT32;
1283 U(propvar).ulVal = 123;
1284 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1285 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1286 PropVariantInit(&ret_propvar);
1287 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1288 U(ret_propvar).ulVal = 0xdeadbeef;
1289 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1290 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1291 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1292 PropVariantClear(&ret_propvar);
1293 CHECK_ATTR_COUNT(attributes, 1);
1295 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1296 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
1298 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1299 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1301 PropVariantInit(&ret_propvar);
1302 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1303 U(ret_propvar).pwszVal = NULL;
1304 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1305 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1306 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1307 PropVariantClear(&ret_propvar);
1309 PropVariantClear(&propvar);
1311 PropVariantInit(&propvar);
1312 propvar.vt = MF_ATTRIBUTE_UINT64;
1313 U(propvar).uhVal.QuadPart = 65536;
1314 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1315 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1316 PropVariantInit(&ret_propvar);
1317 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1318 U(ret_propvar).ulVal = 0xdeadbeef;
1319 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1320 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1321 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1322 PropVariantClear(&ret_propvar);
1323 PropVariantClear(&propvar);
1324 CHECK_ATTR_COUNT(attributes, 1);
1326 PropVariantInit(&propvar);
1327 propvar.vt = VT_I4;
1328 U(propvar).lVal = 123;
1329 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1330 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
1331 PropVariantInit(&ret_propvar);
1332 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1333 U(ret_propvar).lVal = 0xdeadbeef;
1334 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1335 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1336 PropVariantClear(&propvar);
1337 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1338 PropVariantClear(&ret_propvar);
1340 PropVariantInit(&propvar);
1341 propvar.vt = MF_ATTRIBUTE_UINT32;
1342 U(propvar).ulVal = 123;
1343 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1344 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1346 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1347 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1348 CHECK_ATTR_COUNT(attributes, 2);
1350 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1351 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1352 CHECK_ATTR_COUNT(attributes, 2);
1354 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1355 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1356 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1357 PropVariantClear(&ret_propvar);
1358 PropVariantClear(&propvar);
1360 propvar.vt = MF_ATTRIBUTE_UINT64;
1361 U(propvar).uhVal.QuadPart = 65536;
1363 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1364 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1365 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1366 PropVariantClear(&ret_propvar);
1367 PropVariantClear(&propvar);
1369 /* Item ordering is not consistent across Windows version. */
1370 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1371 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1372 PropVariantClear(&ret_propvar);
1374 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1375 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1376 PropVariantClear(&ret_propvar);
1378 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1379 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
1380 CHECK_ATTR_COUNT(attributes, 3);
1381 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1383 double_value = 0xdeadbeef;
1384 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1385 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
1386 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1388 propvar.vt = MF_ATTRIBUTE_UINT64;
1389 U(propvar).uhVal.QuadPart = 22;
1390 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1391 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1392 ok(!result, "Unexpected result.\n");
1394 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1395 U(propvar).dblVal = 22.0;
1396 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1397 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1398 ok(result, "Unexpected result.\n");
1400 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1401 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
1402 CHECK_ATTR_COUNT(attributes, 3);
1403 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1405 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1406 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
1407 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1409 string_length = 0xdeadbeef;
1410 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1411 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
1412 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1413 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1414 CoTaskMemFree(string);
1416 string_length = 0xdeadbeef;
1417 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1418 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1419 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1420 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1421 memset(bufferW, 0, sizeof(bufferW));
1423 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1424 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1425 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1426 memset(bufferW, 0, sizeof(bufferW));
1428 string_length = 0;
1429 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1430 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1431 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1432 ok(string_length, "Unexpected length.\n");
1434 string_length = 0xdeadbeef;
1435 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1436 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1437 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1439 /* VT_UNKNOWN */
1440 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1441 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1442 CHECK_ATTR_COUNT(attributes, 4);
1443 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1445 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1446 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1447 IUnknown_Release(unk_value);
1449 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1450 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1451 IUnknown_Release(unk_value);
1453 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1454 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1456 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1457 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1458 CHECK_ATTR_COUNT(attributes, 5);
1460 unk_value = NULL;
1461 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1462 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1464 /* CopyAllItems() */
1465 hr = MFCreateAttributes(&attributes1, 0);
1466 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1467 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1468 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1469 CHECK_ATTR_COUNT(attributes, 5);
1470 CHECK_ATTR_COUNT(attributes1, 5);
1472 hr = IMFAttributes_DeleteAllItems(attributes1);
1473 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
1474 CHECK_ATTR_COUNT(attributes1, 0);
1476 propvar.vt = MF_ATTRIBUTE_UINT64;
1477 U(propvar).uhVal.QuadPart = 22;
1478 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1479 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1480 ok(!result, "Unexpected result.\n");
1482 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1483 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1484 CHECK_ATTR_COUNT(attributes, 0);
1486 /* Blob */
1487 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1488 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
1489 CHECK_ATTR_COUNT(attributes, 1);
1490 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1491 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1492 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1493 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1495 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1496 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1498 size = 0;
1499 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1500 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1501 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1502 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1504 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1505 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1507 memset(blob_value, 0, sizeof(blob_value));
1508 size = 0;
1509 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1510 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1511 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1512 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1513 CoTaskMemFree(blob_buf);
1515 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1516 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1518 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1519 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1521 IMFAttributes_Release(attributes);
1522 IMFAttributes_Release(attributes1);
1524 /* Compare() */
1525 hr = MFCreateAttributes(&attributes, 0);
1526 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1527 hr = MFCreateAttributes(&attributes1, 0);
1528 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1530 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1531 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1533 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1535 result = FALSE;
1536 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1537 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1538 ok(result, "Unexpected result %d.\n", result);
1540 result = FALSE;
1541 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1542 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1543 ok(result, "Unexpected result %d.\n", result);
1546 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1547 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1549 result = TRUE;
1550 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1551 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1552 ok(!result, "Unexpected result %d.\n", result);
1554 result = TRUE;
1555 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1556 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1557 ok(!result, "Unexpected result %d.\n", result);
1559 result = FALSE;
1560 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1561 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1562 ok(result, "Unexpected result %d.\n", result);
1564 result = FALSE;
1565 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1566 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1567 ok(result, "Unexpected result %d.\n", result);
1569 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1570 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1572 result = TRUE;
1573 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1574 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1575 ok(!result, "Unexpected result %d.\n", result);
1577 result = TRUE;
1578 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1579 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1580 ok(!result, "Unexpected result %d.\n", result);
1582 result = TRUE;
1583 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1584 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1585 ok(!result, "Unexpected result %d.\n", result);
1587 result = TRUE;
1588 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1589 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1590 ok(!result, "Unexpected result %d.\n", result);
1592 result = TRUE;
1593 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1594 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1595 ok(!result, "Unexpected result %d.\n", result);
1597 result = TRUE;
1598 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1599 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1600 ok(!result, "Unexpected result %d.\n", result);
1602 result = TRUE;
1603 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1604 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1605 ok(!result, "Unexpected result %d.\n", result);
1607 result = TRUE;
1608 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1609 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1610 ok(!result, "Unexpected result %d.\n", result);
1612 result = TRUE;
1613 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1614 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1615 ok(!result, "Unexpected result %d.\n", result);
1617 result = TRUE;
1618 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1619 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1620 ok(!result, "Unexpected result %d.\n", result);
1622 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1623 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1625 result = FALSE;
1626 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1627 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1628 ok(result, "Unexpected result %d.\n", result);
1630 result = FALSE;
1631 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1632 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1633 ok(result, "Unexpected result %d.\n", result);
1635 result = FALSE;
1636 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1637 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1638 ok(result, "Unexpected result %d.\n", result);
1640 result = FALSE;
1641 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1642 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1643 ok(result, "Unexpected result %d.\n", result);
1645 result = FALSE;
1646 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1647 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1648 ok(result, "Unexpected result %d.\n", result);
1650 result = FALSE;
1651 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1652 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1653 ok(result, "Unexpected result %d.\n", result);
1655 result = FALSE;
1656 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1657 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1658 ok(result, "Unexpected result %d.\n", result);
1660 result = FALSE;
1661 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1662 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1663 ok(result, "Unexpected result %d.\n", result);
1665 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1666 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1668 result = TRUE;
1669 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1670 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1671 ok(!result, "Unexpected result %d.\n", result);
1673 result = TRUE;
1674 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1675 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1676 ok(!result, "Unexpected result %d.\n", result);
1678 result = FALSE;
1679 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1680 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1681 ok(result, "Unexpected result %d.\n", result);
1683 result = FALSE;
1684 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1685 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1686 ok(result, "Unexpected result %d.\n", result);
1688 result = FALSE;
1689 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1690 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1691 ok(result, "Unexpected result %d.\n", result);
1693 result = TRUE;
1694 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1695 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1696 ok(!result, "Unexpected result %d.\n", result);
1698 result = FALSE;
1699 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1700 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1701 ok(result, "Unexpected result %d.\n", result);
1703 result = TRUE;
1704 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1705 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1706 ok(!result, "Unexpected result %d.\n", result);
1708 result = FALSE;
1709 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1710 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1711 ok(result, "Unexpected result %d.\n", result);
1713 result = FALSE;
1714 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1715 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1716 ok(result, "Unexpected result %d.\n", result);
1718 IMFAttributes_Release(attributes);
1719 IMFAttributes_Release(attributes1);
1722 static void test_MFCreateMFByteStreamOnStream(void)
1724 IMFByteStream *bytestream;
1725 IMFByteStream *bytestream2;
1726 IStream *stream;
1727 IMFAttributes *attributes = NULL;
1728 DWORD caps, written, count;
1729 IUnknown *unknown;
1730 ULONG ref, size;
1731 HRESULT hr;
1733 if(!pMFCreateMFByteStreamOnStream)
1735 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1736 return;
1739 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1740 ok(hr == S_OK, "got 0x%08x\n", hr);
1742 caps = 0xffff0000;
1743 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1744 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1746 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1747 ok(hr == S_OK, "got 0x%08x\n", hr);
1749 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1750 (void **)&unknown);
1751 ok(hr == S_OK, "got 0x%08x\n", hr);
1752 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1753 ref = IUnknown_Release(unknown);
1754 ok(ref == 1, "got %u\n", ref);
1756 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1757 (void **)&bytestream2);
1758 ok(hr == S_OK, "got 0x%08x\n", hr);
1759 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1760 ref = IMFByteStream_Release(bytestream2);
1761 ok(ref == 1, "got %u\n", ref);
1763 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1764 (void **)&attributes);
1765 ok(hr == S_OK ||
1766 /* w7pro64 */
1767 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1769 if (hr != S_OK)
1771 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1772 IStream_Release(stream);
1773 IMFByteStream_Release(bytestream);
1774 return;
1777 ok(attributes != NULL, "got NULL\n");
1778 hr = IMFAttributes_GetCount(attributes, &count);
1779 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1780 ok(count == 0, "Unexpected attributes count %u.\n", count);
1782 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1783 (void **)&unknown);
1784 ok(hr == S_OK, "got 0x%08x\n", hr);
1785 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1786 ref = IUnknown_Release(unknown);
1787 ok(ref == 2, "got %u\n", ref);
1789 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1790 (void **)&bytestream2);
1791 ok(hr == S_OK, "got 0x%08x\n", hr);
1792 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1793 ref = IMFByteStream_Release(bytestream2);
1794 ok(ref == 2, "got %u\n", ref);
1796 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1797 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1798 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1799 check_interface(bytestream, &IID_IMFGetService, FALSE);
1801 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1802 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1803 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1805 hr = IMFByteStream_Close(bytestream);
1806 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1808 hr = IMFByteStream_Close(bytestream);
1809 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1811 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1812 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1813 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1815 caps = 0;
1816 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1817 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1818 ok(caps == 0xffff0000, "Unexpected content.\n");
1820 IMFAttributes_Release(attributes);
1821 IMFByteStream_Release(bytestream);
1822 IStream_Release(stream);
1825 static void test_file_stream(void)
1827 static const WCHAR newfilename[] = L"new.mp4";
1828 IMFByteStream *bytestream, *bytestream2;
1829 QWORD bytestream_length, position;
1830 IMFAttributes *attributes = NULL;
1831 MF_ATTRIBUTE_TYPE item_type;
1832 WCHAR pathW[MAX_PATH];
1833 DWORD caps, count;
1834 WCHAR *filename;
1835 HRESULT hr;
1836 WCHAR *str;
1837 BOOL eos;
1839 filename = load_resource(L"test.mp4");
1841 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1842 ok(hr == S_OK, "got 0x%08x\n", hr);
1844 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1845 MF_FILEFLAGS_NONE, filename, &bytestream);
1846 ok(hr == S_OK, "got 0x%08x\n", hr);
1848 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1849 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1850 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1851 check_interface(bytestream, &IID_IMFGetService, TRUE);
1853 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1854 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1855 if (is_win8_plus)
1857 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1858 "Unexpected caps %#x.\n", caps);
1860 else
1861 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1863 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1864 (void **)&attributes);
1865 ok(hr == S_OK, "got 0x%08x\n", hr);
1866 ok(attributes != NULL, "got NULL\n");
1868 hr = IMFAttributes_GetCount(attributes, &count);
1869 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1870 ok(count == 2, "Unexpected attributes count %u.\n", count);
1872 /* Original file name. */
1873 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1874 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1875 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1876 CoTaskMemFree(str);
1878 /* Modification time. */
1879 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1880 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1881 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1883 IMFAttributes_Release(attributes);
1885 /* Length. */
1886 hr = IMFByteStream_GetLength(bytestream, NULL);
1887 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1889 bytestream_length = 0;
1890 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1891 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1892 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1894 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1895 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1897 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1898 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1899 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1901 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1902 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1904 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1905 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1907 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1908 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1909 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1911 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1912 MF_FILEFLAGS_NONE, filename, &bytestream2);
1913 ok(hr == S_OK, "got 0x%08x\n", hr);
1914 IMFByteStream_Release(bytestream2);
1916 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1917 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1919 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1920 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1922 IMFByteStream_Release(bytestream);
1924 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1925 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1926 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1928 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1929 MF_FILEFLAGS_NONE, filename, &bytestream);
1930 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1932 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1933 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1934 ok(hr == S_OK, "got 0x%08x\n", hr);
1936 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1937 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1939 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1940 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1942 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1943 newfilename, &bytestream2);
1944 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1946 IMFByteStream_Release(bytestream);
1948 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1949 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1950 ok(hr == S_OK, "got 0x%08x\n", hr);
1952 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1953 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1954 newfilename, &bytestream2);
1955 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1957 IMFByteStream_Release(bytestream);
1959 /* Explicit file: scheme */
1960 lstrcpyW(pathW, fileschemeW);
1961 lstrcatW(pathW, filename);
1962 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
1963 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1965 hr = MFShutdown();
1966 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1968 DeleteFileW(filename);
1969 DeleteFileW(newfilename);
1972 static void test_system_memory_buffer(void)
1974 IMFMediaBuffer *buffer;
1975 HRESULT hr;
1976 DWORD length, max;
1977 BYTE *data, *data2;
1979 hr = MFCreateMemoryBuffer(1024, NULL);
1980 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
1982 hr = MFCreateMemoryBuffer(0, &buffer);
1983 ok(hr == S_OK, "got 0x%08x\n", hr);
1984 if(buffer)
1986 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
1987 ok(hr == S_OK, "got 0x%08x\n", hr);
1988 ok(length == 0, "got %u\n", length);
1990 IMFMediaBuffer_Release(buffer);
1993 hr = MFCreateMemoryBuffer(1024, &buffer);
1994 ok(hr == S_OK, "got 0x%08x\n", hr);
1996 check_interface(buffer, &IID_IMFGetService, FALSE);
1998 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
1999 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2001 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2002 ok(hr == S_OK, "got 0x%08x\n", hr);
2003 ok(length == 1024, "got %u\n", length);
2005 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2006 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2008 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2009 ok(hr == S_OK, "got 0x%08x\n", hr);
2011 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2012 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2014 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2015 ok(hr == S_OK, "got 0x%08x\n", hr);
2016 ok(length == 10, "got %u\n", length);
2018 length = 0;
2019 max = 0;
2020 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2021 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2022 ok(length == 0, "got %u\n", length);
2023 ok(max == 0, "got %u\n", length);
2025 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2026 ok(hr == S_OK, "got 0x%08x\n", hr);
2027 ok(length == 10, "got %u\n", length);
2028 ok(max == 1024, "got %u\n", max);
2030 /* Attempt to lock the buffer twice */
2031 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2032 ok(hr == S_OK, "got 0x%08x\n", hr);
2033 ok(data == data2, "got 0x%08x\n", hr);
2035 hr = IMFMediaBuffer_Unlock(buffer);
2036 ok(hr == S_OK, "got 0x%08x\n", hr);
2038 hr = IMFMediaBuffer_Unlock(buffer);
2039 ok(hr == S_OK, "got 0x%08x\n", hr);
2041 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2042 ok(hr == S_OK, "got 0x%08x\n", hr);
2044 hr = IMFMediaBuffer_Unlock(buffer);
2045 ok(hr == S_OK, "got 0x%08x\n", hr);
2047 /* Extra Unlock */
2048 hr = IMFMediaBuffer_Unlock(buffer);
2049 ok(hr == S_OK, "got 0x%08x\n", hr);
2051 IMFMediaBuffer_Release(buffer);
2053 /* Aligned buffer. */
2054 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2055 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2057 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2058 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
2060 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2061 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2062 ok(length == 0, "Unexpected current length %u.\n", length);
2064 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2065 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2066 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2067 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2068 ok(length == 1, "Unexpected current length %u.\n", length);
2070 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2071 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2072 ok(length == 201, "Unexpected max length %u.\n", length);
2074 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2075 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2076 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2077 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2078 ok(length == 201, "Unexpected max length %u.\n", length);
2079 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2080 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2082 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2083 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
2084 ok(max == 201 && length == 10, "Unexpected length.\n");
2085 hr = IMFMediaBuffer_Unlock(buffer);
2086 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2088 IMFMediaBuffer_Release(buffer);
2091 static void test_sample(void)
2093 static const DWORD test_pattern = 0x22222222;
2094 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2095 DWORD count, flags, length;
2096 IMFAttributes *attributes;
2097 IMFSample *sample;
2098 LONGLONG time;
2099 HRESULT hr;
2100 BYTE *data;
2102 hr = MFCreateSample( &sample );
2103 ok(hr == S_OK, "got 0x%08x\n", hr);
2105 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2106 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
2108 CHECK_ATTR_COUNT(attributes, 0);
2110 hr = IMFSample_GetBufferCount(sample, NULL);
2111 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2113 hr = IMFSample_GetBufferCount(sample, &count);
2114 ok(hr == S_OK, "got 0x%08x\n", hr);
2115 ok(count == 0, "got %d\n", count);
2117 hr = IMFSample_GetSampleFlags(sample, &flags);
2118 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2119 ok(!flags, "Unexpected flags %#x.\n", flags);
2121 hr = IMFSample_SetSampleFlags(sample, 0x123);
2122 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
2123 hr = IMFSample_GetSampleFlags(sample, &flags);
2124 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2125 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2127 hr = IMFSample_GetSampleTime(sample, &time);
2128 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2130 hr = IMFSample_GetSampleDuration(sample, &time);
2131 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2133 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2134 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2136 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2137 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2139 hr = IMFSample_RemoveAllBuffers(sample);
2140 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
2142 hr = IMFSample_GetTotalLength(sample, &length);
2143 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2144 ok(!length, "Unexpected total length %u.\n", length);
2146 hr = MFCreateMemoryBuffer(16, &buffer);
2147 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
2149 hr = IMFSample_AddBuffer(sample, buffer);
2150 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2152 hr = IMFSample_AddBuffer(sample, buffer);
2153 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2155 hr = IMFSample_GetBufferCount(sample, &count);
2156 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2157 ok(count == 2, "Unexpected buffer count %u.\n", count);
2159 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2160 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
2161 ok(buffer2 == buffer, "Unexpected object.\n");
2162 IMFMediaBuffer_Release(buffer2);
2164 hr = IMFSample_GetTotalLength(sample, &length);
2165 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2166 ok(!length, "Unexpected total length %u.\n", length);
2168 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2169 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2171 hr = IMFSample_GetTotalLength(sample, &length);
2172 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2173 ok(length == 4, "Unexpected total length %u.\n", length);
2175 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2176 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
2178 hr = IMFSample_GetTotalLength(sample, &length);
2179 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2180 ok(length == 2, "Unexpected total length %u.\n", length);
2182 IMFMediaBuffer_Release(buffer);
2184 /* Duration */
2185 hr = IMFSample_SetSampleDuration(sample, 10);
2186 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
2187 CHECK_ATTR_COUNT(attributes, 0);
2188 hr = IMFSample_GetSampleDuration(sample, &time);
2189 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
2190 ok(time == 10, "Unexpected duration.\n");
2192 /* Timestamp */
2193 hr = IMFSample_SetSampleTime(sample, 1);
2194 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
2195 CHECK_ATTR_COUNT(attributes, 0);
2196 hr = IMFSample_GetSampleTime(sample, &time);
2197 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
2198 ok(time == 1, "Unexpected timestamp.\n");
2200 IMFAttributes_Release(attributes);
2201 IMFSample_Release(sample);
2203 /* CopyToBuffer() */
2204 hr = MFCreateSample(&sample);
2205 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2207 hr = MFCreateMemoryBuffer(16, &buffer2);
2208 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2210 /* Sample with no buffers. */
2211 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2212 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2213 hr = IMFSample_CopyToBuffer(sample, buffer2);
2214 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2215 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2216 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2217 ok(!length, "Unexpected length %u.\n", length);
2219 /* Single buffer, larger destination. */
2220 hr = MFCreateMemoryBuffer(8, &buffer);
2221 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2223 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2224 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2225 *(DWORD *)data = 0x11111111;
2226 hr = IMFMediaBuffer_Unlock(buffer);
2227 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2228 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2229 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2231 hr = IMFSample_AddBuffer(sample, buffer);
2232 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2234 /* Existing content is overwritten. */
2235 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2236 ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
2238 hr = IMFSample_CopyToBuffer(sample, buffer2);
2239 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2241 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2242 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2243 ok(length == 4, "Unexpected buffer length %u.\n", length);
2245 /* Multiple buffers, matching total size. */
2246 hr = IMFSample_AddBuffer(sample, buffer);
2247 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2249 hr = IMFSample_GetBufferCount(sample, &count);
2250 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2251 ok(count == 2, "Unexpected buffer count %u.\n", count);
2253 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2254 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2256 hr = IMFSample_CopyToBuffer(sample, buffer2);
2257 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2259 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2260 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2261 ok(length == 16, "Unexpected buffer length %u.\n", length);
2263 hr = IMFSample_AddBuffer(sample, buffer);
2264 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2266 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2267 ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
2269 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2270 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2271 *(DWORD *)data = test_pattern;
2272 hr = IMFMediaBuffer_Unlock(buffer2);
2273 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2275 hr = IMFSample_CopyToBuffer(sample, buffer2);
2276 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
2278 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2279 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2280 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
2281 hr = IMFMediaBuffer_Unlock(buffer2);
2282 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2284 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2285 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2286 ok(!length, "Unexpected buffer length %u.\n", length);
2288 IMFMediaBuffer_Release(buffer2);
2289 IMFSample_Release(sample);
2291 /* ConvertToContiguousBuffer() */
2292 hr = MFCreateSample(&sample);
2293 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2295 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2296 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2298 hr = MFCreateMemoryBuffer(16, &buffer);
2299 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2301 hr = IMFSample_AddBuffer(sample, buffer);
2302 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2304 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2305 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2306 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2307 IMFMediaBuffer_Release(buffer2);
2309 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2310 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2312 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2313 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2314 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2315 IMFMediaBuffer_Release(buffer2);
2317 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2318 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2320 hr = MFCreateMemoryBuffer(16, &buffer2);
2321 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2323 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2324 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2326 hr = IMFSample_AddBuffer(sample, buffer2);
2327 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2328 IMFMediaBuffer_Release(buffer2);
2330 hr = IMFSample_GetBufferCount(sample, &count);
2331 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2332 ok(count == 2, "Unexpected buffer count %u.\n", count);
2334 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2335 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2337 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2338 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2339 ok(length == 7, "Unexpected length %u.\n", length);
2341 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2342 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2343 ok(length == 7, "Unexpected length %u.\n", length);
2345 IMFMediaBuffer_Release(buffer3);
2347 hr = IMFSample_GetBufferCount(sample, &count);
2348 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2349 ok(count == 1, "Unexpected buffer count %u.\n", count);
2351 hr = IMFSample_AddBuffer(sample, buffer);
2352 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2354 hr = IMFSample_GetBufferCount(sample, &count);
2355 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2356 ok(count == 2, "Unexpected buffer count %u.\n", count);
2358 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2359 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2361 hr = IMFSample_GetBufferCount(sample, &count);
2362 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2363 ok(count == 1, "Unexpected buffer count %u.\n", count);
2365 IMFMediaBuffer_Release(buffer);
2367 IMFSample_Release(sample);
2370 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2372 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2373 IMFMediaEventQueue *queue;
2374 IUnknown *state, *obj;
2375 HRESULT hr;
2377 ok(result != NULL, "Unexpected result object.\n");
2379 state = IMFAsyncResult_GetStateNoAddRef(result);
2380 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2382 IMFMediaEvent *event = NULL, *event2;
2384 if (is_win8_plus)
2386 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2387 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2389 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2390 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2392 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2393 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
2395 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2396 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
2398 if (event)
2399 IMFMediaEvent_Release(event);
2402 hr = IMFAsyncResult_GetObject(result, &obj);
2403 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2405 IMFMediaEventQueue_Release(queue);
2407 SetEvent(callback->event);
2410 return E_NOTIMPL;
2413 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2415 testcallback_QueryInterface,
2416 testcallback_AddRef,
2417 testcallback_Release,
2418 testcallback_GetParameters,
2419 testcallback_Invoke,
2422 static void init_test_callback(struct test_callback *callback)
2424 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
2425 callback->event = NULL;
2428 static void test_MFCreateAsyncResult(void)
2430 IMFAsyncResult *result, *result2;
2431 struct test_callback callback;
2432 IUnknown *state, *object;
2433 MFASYNCRESULT *data;
2434 ULONG refcount;
2435 HANDLE event;
2436 DWORD flags;
2437 HRESULT hr;
2438 BOOL ret;
2440 init_test_callback(&callback);
2442 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2443 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2445 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2446 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2448 data = (MFASYNCRESULT *)result;
2449 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2450 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2451 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2452 ok(data->hEvent == NULL, "Unexpected event.\n");
2454 hr = IMFAsyncResult_GetState(result, NULL);
2455 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2457 state = (void *)0xdeadbeef;
2458 hr = IMFAsyncResult_GetState(result, &state);
2459 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2460 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2462 hr = IMFAsyncResult_GetStatus(result);
2463 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
2465 data->hrStatusResult = 123;
2466 hr = IMFAsyncResult_GetStatus(result);
2467 ok(hr == 123, "Unexpected status %#x.\n", hr);
2469 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2470 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
2471 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
2473 hr = IMFAsyncResult_GetObject(result, NULL);
2474 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2476 object = (void *)0xdeadbeef;
2477 hr = IMFAsyncResult_GetObject(result, &object);
2478 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
2479 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2481 state = IMFAsyncResult_GetStateNoAddRef(result);
2482 ok(state == NULL, "Unexpected state.\n");
2484 /* Object. */
2485 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
2486 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2488 data = (MFASYNCRESULT *)result2;
2489 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2490 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2491 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2492 ok(data->hEvent == NULL, "Unexpected event.\n");
2494 object = NULL;
2495 hr = IMFAsyncResult_GetObject(result2, &object);
2496 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
2497 ok(object == (IUnknown *)result, "Unexpected object.\n");
2498 IUnknown_Release(object);
2500 IMFAsyncResult_Release(result2);
2502 /* State object. */
2503 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2504 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2506 data = (MFASYNCRESULT *)result2;
2507 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2508 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2509 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2510 ok(data->hEvent == NULL, "Unexpected event.\n");
2512 state = NULL;
2513 hr = IMFAsyncResult_GetState(result2, &state);
2514 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
2515 ok(state == (IUnknown *)result, "Unexpected state.\n");
2516 IUnknown_Release(state);
2518 state = IMFAsyncResult_GetStateNoAddRef(result2);
2519 ok(state == (IUnknown *)result, "Unexpected state.\n");
2521 refcount = IMFAsyncResult_Release(result2);
2522 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2523 refcount = IMFAsyncResult_Release(result);
2524 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2526 /* Event handle is closed on release. */
2527 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2528 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2530 data = (MFASYNCRESULT *)result;
2531 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2532 ok(data->hEvent != NULL, "Failed to create event.\n");
2533 ret = GetHandleInformation(event, &flags);
2534 ok(ret, "Failed to get handle info.\n");
2536 refcount = IMFAsyncResult_Release(result);
2537 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2538 ret = GetHandleInformation(event, &flags);
2539 ok(!ret, "Expected handle to be closed.\n");
2541 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2542 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2544 data = (MFASYNCRESULT *)result;
2545 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2546 ok(data->hEvent != NULL, "Failed to create event.\n");
2547 ret = GetHandleInformation(event, &flags);
2548 ok(ret, "Failed to get handle info.\n");
2550 refcount = IMFAsyncResult_Release(result);
2551 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2552 ret = GetHandleInformation(event, &flags);
2553 ok(!ret, "Expected handle to be closed.\n");
2556 static void test_startup(void)
2558 DWORD queue;
2559 HRESULT hr;
2561 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2562 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
2564 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2565 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2567 hr = MFAllocateWorkQueue(&queue);
2568 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2569 hr = MFUnlockWorkQueue(queue);
2570 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2572 hr = MFShutdown();
2573 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2575 hr = MFAllocateWorkQueue(&queue);
2576 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2578 /* Already shut down, has no effect. */
2579 hr = MFShutdown();
2580 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2582 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2583 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2585 hr = MFAllocateWorkQueue(&queue);
2586 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2587 hr = MFUnlockWorkQueue(queue);
2588 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2590 hr = MFShutdown();
2591 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2593 /* Platform lock. */
2594 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2595 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2597 hr = MFAllocateWorkQueue(&queue);
2598 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2599 hr = MFUnlockWorkQueue(queue);
2600 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2602 /* Unlocking implies shutdown. */
2603 hr = MFUnlockPlatform();
2604 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2606 hr = MFAllocateWorkQueue(&queue);
2607 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2609 hr = MFLockPlatform();
2610 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2612 hr = MFAllocateWorkQueue(&queue);
2613 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2614 hr = MFUnlockWorkQueue(queue);
2615 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2617 hr = MFShutdown();
2618 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2621 static void test_allocate_queue(void)
2623 DWORD queue, queue2;
2624 HRESULT hr;
2626 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2627 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2629 hr = MFAllocateWorkQueue(&queue);
2630 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2631 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2633 hr = MFUnlockWorkQueue(queue);
2634 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2636 hr = MFUnlockWorkQueue(queue);
2637 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2639 hr = MFAllocateWorkQueue(&queue2);
2640 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2641 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2643 hr = MFUnlockWorkQueue(queue2);
2644 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2646 /* Unlock in system queue range. */
2647 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2648 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2650 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2651 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2653 hr = MFUnlockWorkQueue(0x20);
2654 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2656 hr = MFShutdown();
2657 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2660 static void test_MFCopyImage(void)
2662 BYTE dest[16], src[16];
2663 HRESULT hr;
2665 if (!pMFCopyImage)
2667 win_skip("MFCopyImage() is not available.\n");
2668 return;
2671 memset(dest, 0xaa, sizeof(dest));
2672 memset(src, 0x11, sizeof(src));
2674 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2675 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2676 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2678 memset(dest, 0xaa, sizeof(dest));
2679 memset(src, 0x11, sizeof(src));
2681 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2682 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2683 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2685 memset(dest, 0xaa, sizeof(dest));
2686 memset(src, 0x11, sizeof(src));
2688 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2689 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2690 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2693 static void test_MFCreateCollection(void)
2695 IMFCollection *collection;
2696 IUnknown *element;
2697 DWORD count;
2698 HRESULT hr;
2700 hr = MFCreateCollection(NULL);
2701 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2703 hr = MFCreateCollection(&collection);
2704 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2706 hr = IMFCollection_GetElementCount(collection, NULL);
2707 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2709 count = 1;
2710 hr = IMFCollection_GetElementCount(collection, &count);
2711 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2712 ok(count == 0, "Unexpected count %u.\n", count);
2714 hr = IMFCollection_GetElement(collection, 0, NULL);
2715 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2717 element = (void *)0xdeadbeef;
2718 hr = IMFCollection_GetElement(collection, 0, &element);
2719 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2720 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2722 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2723 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2725 element = (void *)0xdeadbeef;
2726 hr = IMFCollection_RemoveElement(collection, 0, &element);
2727 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2728 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2730 hr = IMFCollection_RemoveAllElements(collection);
2731 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2733 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2734 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2736 count = 0;
2737 hr = IMFCollection_GetElementCount(collection, &count);
2738 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2739 ok(count == 1, "Unexpected count %u.\n", count);
2741 hr = IMFCollection_AddElement(collection, NULL);
2742 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2744 count = 0;
2745 hr = IMFCollection_GetElementCount(collection, &count);
2746 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2747 ok(count == 2, "Unexpected count %u.\n", count);
2749 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2750 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2752 count = 0;
2753 hr = IMFCollection_GetElementCount(collection, &count);
2754 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2755 ok(count == 11, "Unexpected count %u.\n", count);
2757 hr = IMFCollection_GetElement(collection, 0, &element);
2758 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2759 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2760 IUnknown_Release(element);
2762 hr = IMFCollection_GetElement(collection, 1, &element);
2763 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2764 ok(!element, "Unexpected element.\n");
2766 hr = IMFCollection_GetElement(collection, 2, &element);
2767 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2768 ok(!element, "Unexpected element.\n");
2770 hr = IMFCollection_GetElement(collection, 10, &element);
2771 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2772 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2773 IUnknown_Release(element);
2775 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2776 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2778 hr = IMFCollection_GetElement(collection, 0, &element);
2779 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2781 hr = IMFCollection_RemoveAllElements(collection);
2782 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2784 count = 1;
2785 hr = IMFCollection_GetElementCount(collection, &count);
2786 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2787 ok(count == 0, "Unexpected count %u.\n", count);
2789 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2790 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2792 IMFCollection_Release(collection);
2795 static void test_MFHeapAlloc(void)
2797 void *res;
2799 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2800 ok(res != NULL, "MFHeapAlloc failed.\n");
2802 MFHeapFree(res);
2805 static void test_scheduled_items(void)
2807 struct test_callback callback;
2808 IMFAsyncResult *result;
2809 MFWORKITEM_KEY key, key2;
2810 HRESULT hr;
2812 init_test_callback(&callback);
2814 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2815 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2817 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2818 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2820 hr = MFCancelWorkItem(key);
2821 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2823 hr = MFCancelWorkItem(key);
2824 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2826 if (!pMFPutWaitingWorkItem)
2828 win_skip("Waiting items are not supported.\n");
2829 return;
2832 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2833 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2835 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2836 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2838 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2839 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2841 hr = MFCancelWorkItem(key);
2842 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2844 hr = MFCancelWorkItem(key2);
2845 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2847 IMFAsyncResult_Release(result);
2849 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2850 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2852 hr = MFCancelWorkItem(key);
2853 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2855 hr = MFShutdown();
2856 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2859 static void test_serial_queue(void)
2861 static const DWORD queue_ids[] =
2863 MFASYNC_CALLBACK_QUEUE_STANDARD,
2864 MFASYNC_CALLBACK_QUEUE_RT,
2865 MFASYNC_CALLBACK_QUEUE_IO,
2866 MFASYNC_CALLBACK_QUEUE_TIMER,
2867 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2868 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2870 DWORD queue, serial_queue;
2871 unsigned int i;
2872 HRESULT hr;
2874 if (!pMFAllocateSerialWorkQueue)
2876 win_skip("Serial queues are not supported.\n");
2877 return;
2880 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2881 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2883 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2885 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2886 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2888 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2889 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2890 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2892 if (SUCCEEDED(hr))
2894 hr = MFUnlockWorkQueue(serial_queue);
2895 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2899 /* Chain them together. */
2900 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2901 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2903 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2904 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2906 hr = MFUnlockWorkQueue(serial_queue);
2907 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2909 hr = MFUnlockWorkQueue(queue);
2910 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2912 hr = MFShutdown();
2913 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2916 static LONG periodic_counter;
2917 static void CALLBACK periodic_callback(IUnknown *context)
2919 InterlockedIncrement(&periodic_counter);
2922 static void test_periodic_callback(void)
2924 DWORD period, key;
2925 HRESULT hr;
2927 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2928 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2930 period = 0;
2931 hr = MFGetTimerPeriodicity(&period);
2932 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2933 ok(period == 10, "Unexpected period %u.\n", period);
2935 if (!pMFAddPeriodicCallback)
2937 win_skip("Periodic callbacks are not supported.\n");
2938 hr = MFShutdown();
2939 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2940 return;
2943 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2945 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2946 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2947 ok(key != 0, "Unexpected key %#x.\n", key);
2949 Sleep(10 * period);
2951 hr = pMFRemovePeriodicCallback(key);
2952 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2954 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2956 hr = MFShutdown();
2957 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2960 static void test_event_queue(void)
2962 struct test_callback callback, callback2;
2963 IMFMediaEvent *event, *event2;
2964 IMFMediaEventQueue *queue;
2965 IMFAsyncResult *result;
2966 HRESULT hr;
2967 DWORD ret;
2969 init_test_callback(&callback);
2970 init_test_callback(&callback2);
2972 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2973 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2975 hr = MFCreateEventQueue(&queue);
2976 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
2978 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2979 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
2981 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
2982 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
2984 if (is_win8_plus)
2986 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2987 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2989 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
2990 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2991 ok(event2 == event, "Unexpected event object.\n");
2992 IMFMediaEvent_Release(event2);
2994 hr = IMFMediaEventQueue_QueueEvent(queue, event);
2995 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
2997 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
2998 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2999 IMFMediaEvent_Release(event2);
3002 /* Async case. */
3003 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3004 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3006 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3007 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
3009 /* Same callback, same state. */
3010 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3011 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3013 /* Same callback, different state. */
3014 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
3015 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3017 /* Different callback, same state. */
3018 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
3019 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3021 /* Different callback, different state. */
3022 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
3023 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3025 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
3027 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3028 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3030 ret = WaitForSingleObject(callback.event, 500);
3031 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
3033 CloseHandle(callback.event);
3035 IMFMediaEvent_Release(event);
3037 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3038 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
3040 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3041 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3043 /* Shutdown behavior. */
3044 hr = IMFMediaEventQueue_Shutdown(queue);
3045 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3047 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3048 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3050 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3051 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3052 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3053 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3054 IMFMediaEvent_Release(event);
3056 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3057 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3059 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3060 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3062 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
3063 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3065 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3066 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3068 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3069 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3070 IMFAsyncResult_Release(result);
3072 /* Already shut down. */
3073 hr = IMFMediaEventQueue_Shutdown(queue);
3074 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3076 IMFMediaEventQueue_Release(queue);
3078 hr = MFShutdown();
3079 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3082 static void test_presentation_descriptor(void)
3084 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3085 IMFPresentationDescriptor *pd, *pd2;
3086 IMFMediaType *media_type;
3087 unsigned int i;
3088 BOOL selected;
3089 UINT64 value;
3090 DWORD count;
3091 HRESULT hr;
3093 hr = MFCreateMediaType(&media_type);
3094 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3096 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3098 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3099 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3102 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3103 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
3105 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3106 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
3108 for (i = 0; i < count; ++i)
3110 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3111 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3112 ok(!selected, "Unexpected selected state.\n");
3113 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3114 IMFStreamDescriptor_Release(stream_desc2);
3117 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3118 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3120 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3121 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3123 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3124 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
3126 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3127 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3128 ok(!!selected, "Unexpected selected state.\n");
3129 IMFStreamDescriptor_Release(stream_desc2);
3131 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3132 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3134 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3135 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
3137 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3138 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3139 ok(!!selected, "Unexpected selected state.\n");
3140 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3141 IMFStreamDescriptor_Release(stream_desc2);
3143 value = 0;
3144 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3145 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3146 ok(value == 1, "Unexpected attribute value.\n");
3148 IMFPresentationDescriptor_Release(pd2);
3149 IMFPresentationDescriptor_Release(pd);
3151 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3153 IMFStreamDescriptor_Release(stream_desc[i]);
3156 /* Partially initialized array. */
3157 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3158 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3159 stream_desc[0] = NULL;
3161 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3162 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3164 IMFStreamDescriptor_Release(stream_desc[1]);
3165 IMFMediaType_Release(media_type);
3168 enum clock_action
3170 CLOCK_START,
3171 CLOCK_STOP,
3172 CLOCK_PAUSE,
3173 CLOCK_RESTART,
3176 static void test_system_time_source(void)
3178 static const struct clock_state_test
3180 enum clock_action action;
3181 MFCLOCK_STATE state;
3182 BOOL is_invalid;
3184 clock_state_change[] =
3186 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3187 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3188 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3189 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3190 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3191 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3192 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3193 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3194 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3195 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3196 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3197 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3198 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3199 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3200 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3201 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3202 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3204 IMFPresentationTimeSource *time_source, *time_source2;
3205 IMFClockStateSink *statesink;
3206 IMFClock *clock, *clock2;
3207 MFCLOCK_PROPERTIES props;
3208 MFCLOCK_STATE state;
3209 unsigned int i;
3210 MFTIME systime;
3211 LONGLONG time;
3212 DWORD value;
3213 HRESULT hr;
3215 hr = MFCreateSystemTimeSource(&time_source);
3216 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3218 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3219 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
3220 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3221 "Unexpected flags %#x.\n", value);
3223 value = 1;
3224 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3225 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3226 ok(value == 0, "Unexpected value %u.\n", value);
3228 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3229 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
3230 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3232 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3233 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
3235 /* State changes. */
3236 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3238 switch (clock_state_change[i].action)
3240 case CLOCK_STOP:
3241 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3242 break;
3243 case CLOCK_RESTART:
3244 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3245 break;
3246 case CLOCK_PAUSE:
3247 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3248 break;
3249 case CLOCK_START:
3250 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3251 break;
3252 default:
3255 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
3256 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3257 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
3258 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3261 IMFClockStateSink_Release(statesink);
3263 /* Properties. */
3264 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3265 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3267 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3268 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3270 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3271 wine_dbgstr_longlong(props.qwCorrelationRate));
3272 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3273 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3274 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3275 wine_dbgstr_longlong(props.qwClockFrequency));
3276 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3277 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3279 /* Underlying clock. */
3280 hr = MFCreateSystemTimeSource(&time_source2);
3281 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3282 EXPECT_REF(time_source2, 1);
3283 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3284 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3285 EXPECT_REF(time_source2, 1);
3286 EXPECT_REF(clock2, 2);
3288 EXPECT_REF(time_source, 1);
3289 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3290 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3291 EXPECT_REF(time_source, 1);
3292 EXPECT_REF(clock, 2);
3294 ok(clock != clock2, "Unexpected clock instance.\n");
3296 IMFPresentationTimeSource_Release(time_source2);
3297 IMFClock_Release(clock2);
3299 hr = IMFClock_GetClockCharacteristics(clock, &value);
3300 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
3301 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3302 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
3304 hr = IMFClock_GetContinuityKey(clock, &value);
3305 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
3306 ok(value == 0, "Unexpected key value %u.\n", value);
3308 hr = IMFClock_GetState(clock, 0, &state);
3309 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
3310 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3312 hr = IMFClock_GetProperties(clock, &props);
3313 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3315 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3316 wine_dbgstr_longlong(props.qwCorrelationRate));
3317 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3318 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3319 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3320 wine_dbgstr_longlong(props.qwClockFrequency));
3321 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3322 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3324 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3325 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
3326 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3328 IMFClock_Release(clock);
3330 /* Test returned time regarding specified rate and offset. */
3331 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3332 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3334 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3335 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
3336 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3338 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3339 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3340 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3342 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3343 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3345 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3346 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3347 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3349 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3350 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3352 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3353 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3354 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3355 wine_dbgstr_longlong(systime));
3357 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3358 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3360 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3361 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3362 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3364 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3365 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3367 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3368 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3369 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3370 wine_dbgstr_longlong(systime));
3372 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3373 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3375 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3376 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3377 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3378 wine_dbgstr_longlong(systime));
3380 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3381 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3383 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3384 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3385 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3387 /* Increased rate. */
3388 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3389 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
3391 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3392 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3394 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3395 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3396 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3397 wine_dbgstr_longlong(2 * systime));
3399 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3400 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3402 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3403 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3404 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3405 wine_dbgstr_longlong(2 * systime));
3407 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3408 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3410 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3411 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3412 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3413 wine_dbgstr_longlong(systime));
3415 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3416 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3418 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3419 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3420 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3421 wine_dbgstr_longlong(systime));
3423 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3424 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3426 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3427 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3428 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3429 wine_dbgstr_longlong(systime));
3431 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3432 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3434 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3435 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3436 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3438 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3439 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3441 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3442 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3443 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3444 wine_dbgstr_longlong(2 * systime));
3446 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3447 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3449 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3450 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3452 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3453 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3454 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3455 wine_dbgstr_longlong(2 * systime));
3457 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3458 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3460 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3461 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3462 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3463 wine_dbgstr_longlong(systime));
3465 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3466 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3468 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3469 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3470 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3471 wine_dbgstr_longlong(systime));
3473 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3474 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3476 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3477 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3478 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3479 wine_dbgstr_longlong(systime));
3481 IMFClockStateSink_Release(statesink);
3482 IMFPresentationTimeSource_Release(time_source);
3484 /* PRESENTATION_CURRENT_POSITION */
3485 hr = MFCreateSystemTimeSource(&time_source);
3486 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3488 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3489 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3491 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3492 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3493 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3494 wine_dbgstr_longlong(systime));
3496 /* INVALID -> RUNNING */
3497 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3498 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3500 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3501 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3502 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3503 wine_dbgstr_longlong(systime));
3505 /* RUNNING -> RUNNING */
3506 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3507 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3509 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3510 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3511 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3512 wine_dbgstr_longlong(systime));
3514 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3515 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3517 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3518 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3519 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3520 wine_dbgstr_longlong(systime));
3522 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3523 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3525 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3526 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3527 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3528 wine_dbgstr_longlong(systime));
3530 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3531 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3533 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3534 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3535 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3536 wine_dbgstr_longlong(systime));
3538 /* STOPPED -> RUNNING */
3539 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3540 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3542 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3543 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3544 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3545 wine_dbgstr_longlong(systime));
3547 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3548 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3550 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3551 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3552 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3553 wine_dbgstr_longlong(systime));
3555 /* PAUSED -> RUNNING */
3556 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3557 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3559 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3560 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3561 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3562 wine_dbgstr_longlong(systime));
3564 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3565 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3567 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3568 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3569 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3570 wine_dbgstr_longlong(systime));
3572 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3573 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3575 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3576 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3577 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3578 wine_dbgstr_longlong(systime));
3580 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3581 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3583 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3584 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3585 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3586 wine_dbgstr_longlong(systime));
3588 IMFClockStateSink_Release(statesink);
3589 IMFPresentationTimeSource_Release(time_source);
3592 static void test_MFInvokeCallback(void)
3594 struct test_callback callback;
3595 IMFAsyncResult *result;
3596 MFASYNCRESULT *data;
3597 ULONG refcount;
3598 HRESULT hr;
3599 DWORD ret;
3601 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3602 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3604 init_test_callback(&callback);
3606 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3607 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3609 data = (MFASYNCRESULT *)result;
3610 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3611 ok(data->hEvent != NULL, "Failed to create event.\n");
3613 hr = MFInvokeCallback(result);
3614 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
3616 ret = WaitForSingleObject(data->hEvent, 100);
3617 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
3619 refcount = IMFAsyncResult_Release(result);
3620 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3622 hr = MFShutdown();
3623 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3626 static void test_stream_descriptor(void)
3628 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3629 IMFMediaTypeHandler *type_handler;
3630 IMFStreamDescriptor *stream_desc;
3631 GUID major_type;
3632 DWORD id, count;
3633 unsigned int i;
3634 HRESULT hr;
3636 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3637 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3639 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3641 hr = MFCreateMediaType(&media_types[i]);
3642 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3645 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3646 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3648 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3649 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3651 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3652 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
3653 ok(id == 123, "Unexpected id %#x.\n", id);
3655 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3656 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3658 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3659 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3660 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3662 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3663 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3665 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3666 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3668 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3670 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3671 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3672 ok(media_type == media_types[i], "Unexpected object.\n");
3674 if (SUCCEEDED(hr))
3675 IMFMediaType_Release(media_type);
3678 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
3679 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3681 /* IsMediaTypeSupported() */
3683 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3684 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3686 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
3687 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3689 hr = MFCreateMediaType(&media_type);
3690 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3692 hr = MFCreateMediaType(&media_type3);
3693 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3695 media_type2 = (void *)0xdeadbeef;
3696 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3697 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3698 ok(!media_type2, "Unexpected pointer.\n");
3700 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3701 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3703 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3704 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3706 media_type2 = (void *)0xdeadbeef;
3707 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3708 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3709 ok(!media_type2, "Unexpected pointer.\n");
3711 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3712 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3714 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3715 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3717 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3718 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3719 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
3721 /* Mismatching major types. */
3722 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3723 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3725 media_type2 = (void *)0xdeadbeef;
3726 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3727 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3728 ok(!media_type2, "Unexpected pointer.\n");
3730 /* Subtype missing. */
3731 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3732 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3734 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3735 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3737 media_type2 = (void *)0xdeadbeef;
3738 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3739 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3740 ok(!media_type2, "Unexpected pointer.\n");
3742 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3743 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3745 media_type2 = (void *)0xdeadbeef;
3746 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3747 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3748 ok(!media_type2, "Unexpected pointer.\n");
3750 /* Mismatching subtype. */
3751 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3752 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3754 media_type2 = (void *)0xdeadbeef;
3755 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3756 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3757 ok(!media_type2, "Unexpected pointer.\n");
3759 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3760 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3761 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3763 IMFMediaTypeHandler_Release(type_handler);
3764 IMFStreamDescriptor_Release(stream_desc);
3766 /* IsMediaTypeSupported() for unset current type. */
3767 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3768 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3770 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3771 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3773 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
3774 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3776 /* Initialize one from initial type set. */
3777 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
3778 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3780 media_type2 = (void *)0xdeadbeef;
3781 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3782 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3783 ok(!media_type2, "Unexpected pointer.\n");
3785 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3786 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3788 media_type2 = (void *)0xdeadbeef;
3789 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3790 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3791 ok(!media_type2, "Unexpected pointer.\n");
3793 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3794 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3796 media_type2 = (void *)0xdeadbeef;
3797 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3798 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3799 ok(!media_type2, "Unexpected pointer.\n");
3801 /* Now set current type that's not compatible. */
3802 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3803 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3805 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3806 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3808 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
3809 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3811 media_type2 = (void *)0xdeadbeef;
3812 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3814 ok(!media_type2, "Unexpected pointer.\n");
3816 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
3817 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3819 media_type2 = (void *)0xdeadbeef;
3820 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3822 ok(!media_type2, "Unexpected pointer.\n");
3824 IMFMediaType_Release(media_type);
3825 IMFMediaType_Release(media_type3);
3827 IMFMediaTypeHandler_Release(type_handler);
3829 IMFStreamDescriptor_Release(stream_desc);
3831 /* Major type is returned for first entry. */
3832 hr = MFCreateMediaType(&media_types[0]);
3833 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3834 hr = MFCreateMediaType(&media_types[1]);
3835 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3837 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3838 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3839 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3840 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3842 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
3843 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3845 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3846 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3848 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3849 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3850 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3852 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3853 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3854 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3855 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3857 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3858 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3859 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3861 IMFMediaType_Release(media_types[0]);
3862 IMFMediaType_Release(media_types[1]);
3864 IMFMediaTypeHandler_Release(type_handler);
3865 IMFStreamDescriptor_Release(stream_desc);
3868 static void test_MFCalculateImageSize(void)
3870 static const struct image_size_test
3872 const GUID *subtype;
3873 UINT32 width;
3874 UINT32 height;
3875 UINT32 size;
3876 UINT32 plane_size; /* Matches image size when 0. */
3878 image_size_tests[] =
3880 { &MFVideoFormat_RGB8, 3, 5, 20 },
3881 { &MFVideoFormat_RGB8, 1, 1, 4 },
3882 { &MFVideoFormat_RGB555, 3, 5, 40 },
3883 { &MFVideoFormat_RGB555, 1, 1, 4 },
3884 { &MFVideoFormat_RGB565, 3, 5, 40 },
3885 { &MFVideoFormat_RGB565, 1, 1, 4 },
3886 { &MFVideoFormat_RGB24, 3, 5, 60 },
3887 { &MFVideoFormat_RGB24, 1, 1, 4 },
3888 { &MFVideoFormat_RGB32, 3, 5, 60 },
3889 { &MFVideoFormat_RGB32, 1, 1, 4 },
3890 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3891 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3892 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3893 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3894 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3895 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3897 /* YUV */
3898 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
3899 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
3900 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
3901 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
3902 { &MFVideoFormat_NV12, 4, 2, 12 },
3903 { &MFVideoFormat_NV12, 320, 240, 115200 },
3904 { &MFVideoFormat_AYUV, 1, 1, 4 },
3905 { &MFVideoFormat_AYUV, 2, 1, 8 },
3906 { &MFVideoFormat_AYUV, 1, 2, 8 },
3907 { &MFVideoFormat_AYUV, 4, 3, 48 },
3908 { &MFVideoFormat_AYUV, 320, 240, 307200 },
3909 { &MFVideoFormat_IMC1, 1, 1, 4 },
3910 { &MFVideoFormat_IMC1, 2, 1, 4 },
3911 { &MFVideoFormat_IMC1, 1, 2, 8 },
3912 { &MFVideoFormat_IMC1, 4, 3, 24 },
3913 { &MFVideoFormat_IMC1, 320, 240, 153600 },
3914 { &MFVideoFormat_IMC3, 1, 1, 4 },
3915 { &MFVideoFormat_IMC3, 2, 1, 4 },
3916 { &MFVideoFormat_IMC3, 1, 2, 8 },
3917 { &MFVideoFormat_IMC3, 4, 3, 24 },
3918 { &MFVideoFormat_IMC3, 320, 240, 153600 },
3919 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
3920 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
3921 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
3922 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
3923 { &MFVideoFormat_IMC2, 4, 2, 12 },
3924 { &MFVideoFormat_IMC2, 320, 240, 115200 },
3925 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
3926 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
3927 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
3928 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
3929 { &MFVideoFormat_IMC4, 4, 2, 12 },
3930 { &MFVideoFormat_IMC4, 320, 240, 115200 },
3931 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
3932 { &MFVideoFormat_YV12, 2, 1, 3 },
3933 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
3934 { &MFVideoFormat_YV12, 4, 3, 18 },
3935 { &MFVideoFormat_YV12, 320, 240, 115200 },
3937 { &MFVideoFormat_I420, 1, 1, 3, 1 },
3938 { &MFVideoFormat_I420, 2, 1, 3 },
3939 { &MFVideoFormat_I420, 1, 2, 6, 3 },
3940 { &MFVideoFormat_I420, 4, 3, 18 },
3941 { &MFVideoFormat_I420, 320, 240, 115200 },
3943 { &MFVideoFormat_YUY2, 2, 1, 4 },
3944 { &MFVideoFormat_YUY2, 4, 3, 24 },
3945 { &MFVideoFormat_YUY2, 128, 128, 32768 },
3946 { &MFVideoFormat_YUY2, 320, 240, 153600 },
3948 { &MFVideoFormat_UYVY, 2, 1, 4 },
3949 { &MFVideoFormat_UYVY, 4, 3, 24 },
3950 { &MFVideoFormat_UYVY, 128, 128, 32768 },
3951 { &MFVideoFormat_UYVY, 320, 240, 153600 },
3953 unsigned int i;
3954 UINT32 size;
3955 HRESULT hr;
3957 if (!pMFGetPlaneSize)
3958 win_skip("MFGetPlaneSize() is not available.\n");
3960 size = 1;
3961 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
3962 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
3963 ok(size == 0, "Unexpected size %u.\n", size);
3965 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
3967 const struct image_size_test *ptr = &image_size_tests[i];
3969 /* Those are supported since Win10. */
3970 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
3971 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
3973 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
3974 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
3975 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
3976 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
3978 if (pMFGetPlaneSize)
3980 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
3982 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
3983 ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
3984 ok(size == plane_size, "%u: unexpected plane size %u, expected %u.\n", i, size, plane_size);
3989 static void test_MFCompareFullToPartialMediaType(void)
3991 IMFMediaType *full_type, *partial_type;
3992 HRESULT hr;
3993 BOOL ret;
3995 hr = MFCreateMediaType(&full_type);
3996 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3998 hr = MFCreateMediaType(&partial_type);
3999 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4001 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4002 ok(!ret, "Unexpected result %d.\n", ret);
4004 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4005 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4007 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4008 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4010 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4011 ok(ret, "Unexpected result %d.\n", ret);
4013 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4014 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4016 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4017 ok(ret, "Unexpected result %d.\n", ret);
4019 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4020 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4022 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4023 ok(!ret, "Unexpected result %d.\n", ret);
4025 IMFMediaType_Release(full_type);
4026 IMFMediaType_Release(partial_type);
4029 static void test_attributes_serialization(void)
4031 static const UINT8 blob[] = {1,2,3};
4032 IMFAttributes *attributes, *dest;
4033 UINT32 size, count, value32;
4034 double value_dbl;
4035 UINT64 value64;
4036 UINT8 *buffer;
4037 IUnknown *obj;
4038 HRESULT hr;
4039 WCHAR *str;
4040 GUID guid;
4042 hr = MFCreateAttributes(&attributes, 0);
4043 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4045 hr = MFCreateAttributes(&dest, 0);
4046 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4048 hr = MFGetAttributesAsBlobSize(attributes, &size);
4049 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4050 ok(size == 8, "Got size %u.\n", size);
4052 buffer = heap_alloc(size);
4054 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4055 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4057 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4058 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
4060 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4061 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4063 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4064 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4066 hr = MFInitAttributesFromBlob(dest, buffer, size);
4067 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4069 /* Previous items are cleared. */
4070 hr = IMFAttributes_GetCount(dest, &count);
4071 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
4072 ok(count == 0, "Unexpected count %u.\n", count);
4074 heap_free(buffer);
4076 /* Set some attributes of various types. */
4077 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4078 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4079 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4080 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4081 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4082 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4083 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4085 hr = MFGetAttributesAsBlobSize(attributes, &size);
4086 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4087 ok(size > 8, "Got unexpected size %u.\n", size);
4089 buffer = heap_alloc(size);
4090 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4091 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4092 hr = MFInitAttributesFromBlob(dest, buffer, size);
4093 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4094 heap_free(buffer);
4096 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4097 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
4098 ok(value32 == 456, "Unexpected value %u.\n", value32);
4099 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4100 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
4101 ok(value64 == 123, "Unexpected value.\n");
4102 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4103 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
4104 ok(value_dbl == 0.5, "Unexpected value.\n");
4105 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4106 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4107 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4108 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
4109 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4110 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4111 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
4112 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4113 CoTaskMemFree(str);
4114 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4115 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
4116 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4117 CoTaskMemFree(buffer);
4119 IMFAttributes_Release(attributes);
4120 IMFAttributes_Release(dest);
4123 static void test_wrapped_media_type(void)
4125 IMFMediaType *mediatype, *mediatype2;
4126 UINT32 count, type;
4127 HRESULT hr;
4128 GUID guid;
4130 hr = MFCreateMediaType(&mediatype);
4131 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4133 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4134 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4136 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4137 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4138 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4139 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4141 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4142 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
4144 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4145 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
4147 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4148 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4149 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4151 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4152 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
4153 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4155 hr = IMFMediaType_GetCount(mediatype2, &count);
4156 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
4157 ok(count == 3, "Unexpected count %u.\n", count);
4159 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4160 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
4161 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4163 IMFMediaType_Release(mediatype);
4165 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4166 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
4168 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4169 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4170 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4172 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4173 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4175 IMFMediaType_Release(mediatype);
4176 IMFMediaType_Release(mediatype2);
4179 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4181 WAVEFORMATEXTENSIBLE *format_ext;
4182 IMFMediaType *mediatype;
4183 WAVEFORMATEX *format;
4184 UINT32 size;
4185 HRESULT hr;
4187 hr = MFCreateMediaType(&mediatype);
4188 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4190 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4191 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4193 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4194 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4196 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4197 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4199 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4200 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4202 /* Audio/PCM */
4203 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4204 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4205 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4206 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4208 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4209 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4210 ok(format != NULL, "Expected format structure.\n");
4211 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4212 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
4213 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4214 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
4215 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
4216 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4217 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4218 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4219 CoTaskMemFree(format);
4221 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4222 MFWaveFormatExConvertFlag_ForceExtensible);
4223 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4224 ok(format_ext != NULL, "Expected format structure.\n");
4225 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4226 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4227 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4228 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
4229 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
4230 format_ext->Format.nAvgBytesPerSec);
4231 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4232 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4233 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4234 format_ext->Format.cbSize);
4235 CoTaskMemFree(format_ext);
4237 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4238 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4239 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4240 CoTaskMemFree(format);
4242 IMFMediaType_Release(mediatype);
4245 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4247 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4248 IMFByteStream *stream;
4249 IUnknown *object;
4250 HRESULT hr;
4252 ok(!!result, "Unexpected result object.\n");
4254 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4256 hr = IMFAsyncResult_GetObject(result, &object);
4257 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4259 hr = MFEndCreateFile(result, &stream);
4260 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
4261 IMFByteStream_Release(stream);
4263 SetEvent(callback->event);
4265 return S_OK;
4268 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4270 testcallback_QueryInterface,
4271 testcallback_AddRef,
4272 testcallback_Release,
4273 testcallback_GetParameters,
4274 test_create_file_callback_Invoke,
4277 static void test_async_create_file(void)
4279 struct test_callback callback = { { &test_create_file_callback_vtbl } };
4280 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4281 IUnknown *cancel_cookie;
4282 HRESULT hr;
4283 BOOL ret;
4285 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4286 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
4288 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
4290 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4291 GetTempFileNameW(pathW, NULL, 0, fileW);
4293 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4294 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
4295 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
4296 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4298 WaitForSingleObject(callback.event, INFINITE);
4300 IUnknown_Release(cancel_cookie);
4302 CloseHandle(callback.event);
4304 hr = MFShutdown();
4305 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4307 ret = DeleteFileW(fileW);
4308 ok(ret, "Failed to delete test file.\n");
4311 struct activate_object
4313 IMFActivate IMFActivate_iface;
4314 LONG refcount;
4317 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4319 if (IsEqualIID(riid, &IID_IMFActivate) ||
4320 IsEqualIID(riid, &IID_IMFAttributes) ||
4321 IsEqualIID(riid, &IID_IUnknown))
4323 *obj = iface;
4324 IMFActivate_AddRef(iface);
4325 return S_OK;
4328 *obj = NULL;
4329 return E_NOINTERFACE;
4332 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4334 return 2;
4337 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4339 return 1;
4342 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4344 return E_NOTIMPL;
4347 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4349 return E_NOTIMPL;
4352 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4354 return E_NOTIMPL;
4357 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4358 BOOL *result)
4360 return E_NOTIMPL;
4363 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4365 return E_NOTIMPL;
4368 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4370 return E_NOTIMPL;
4373 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4375 return E_NOTIMPL;
4378 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4380 return E_NOTIMPL;
4383 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4385 return E_NOTIMPL;
4388 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4389 UINT32 size, UINT32 *length)
4391 return E_NOTIMPL;
4394 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4395 WCHAR **value, UINT32 *length)
4397 return E_NOTIMPL;
4400 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4402 return E_NOTIMPL;
4405 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4406 UINT32 bufsize, UINT32 *blobsize)
4408 return E_NOTIMPL;
4411 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4413 return E_NOTIMPL;
4416 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4418 return E_NOTIMPL;
4421 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4423 return E_NOTIMPL;
4426 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4428 return E_NOTIMPL;
4431 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4433 return E_NOTIMPL;
4436 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4438 return E_NOTIMPL;
4441 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4443 return E_NOTIMPL;
4446 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4448 return E_NOTIMPL;
4451 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4453 return E_NOTIMPL;
4456 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4458 return E_NOTIMPL;
4461 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4463 return E_NOTIMPL;
4466 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4468 return E_NOTIMPL;
4471 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4473 return E_NOTIMPL;
4476 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4478 return E_NOTIMPL;
4481 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4483 return E_NOTIMPL;
4486 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4488 return E_NOTIMPL;
4491 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4493 return E_NOTIMPL;
4496 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4498 return E_NOTIMPL;
4501 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4503 return E_NOTIMPL;
4506 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4508 return E_NOTIMPL;
4511 static const IMFActivateVtbl activate_object_vtbl =
4513 activate_object_QueryInterface,
4514 activate_object_AddRef,
4515 activate_object_Release,
4516 activate_object_GetItem,
4517 activate_object_GetItemType,
4518 activate_object_CompareItem,
4519 activate_object_Compare,
4520 activate_object_GetUINT32,
4521 activate_object_GetUINT64,
4522 activate_object_GetDouble,
4523 activate_object_GetGUID,
4524 activate_object_GetStringLength,
4525 activate_object_GetString,
4526 activate_object_GetAllocatedString,
4527 activate_object_GetBlobSize,
4528 activate_object_GetBlob,
4529 activate_object_GetAllocatedBlob,
4530 activate_object_GetUnknown,
4531 activate_object_SetItem,
4532 activate_object_DeleteItem,
4533 activate_object_DeleteAllItems,
4534 activate_object_SetUINT32,
4535 activate_object_SetUINT64,
4536 activate_object_SetDouble,
4537 activate_object_SetGUID,
4538 activate_object_SetString,
4539 activate_object_SetBlob,
4540 activate_object_SetUnknown,
4541 activate_object_LockStore,
4542 activate_object_UnlockStore,
4543 activate_object_GetCount,
4544 activate_object_GetItemByIndex,
4545 activate_object_CopyAllItems,
4546 activate_object_ActivateObject,
4547 activate_object_ShutdownObject,
4548 activate_object_DetachObject,
4551 static void test_local_handlers(void)
4553 IMFActivate local_activate = { &activate_object_vtbl };
4554 static const WCHAR localW[] = L"local";
4555 HRESULT hr;
4557 if (!pMFRegisterLocalSchemeHandler)
4559 win_skip("Local handlers are not supported.\n");
4560 return;
4563 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4564 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4566 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4567 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4569 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4570 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4572 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4573 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4575 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4576 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4578 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4579 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4581 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4582 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4584 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4585 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4587 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4588 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4590 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4591 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4594 static void test_create_property_store(void)
4596 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4597 IPropertyStore *store, *store2;
4598 PROPVARIANT value = {0};
4599 PROPERTYKEY key;
4600 ULONG refcount;
4601 DWORD count;
4602 HRESULT hr;
4604 hr = CreatePropertyStore(NULL);
4605 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4607 hr = CreatePropertyStore(&store);
4608 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4610 hr = CreatePropertyStore(&store2);
4611 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4612 ok(store2 != store, "Expected different store objects.\n");
4613 IPropertyStore_Release(store2);
4615 check_interface(store, &IID_IPropertyStoreCache, FALSE);
4616 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
4618 hr = IPropertyStore_GetCount(store, NULL);
4619 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4621 count = 0xdeadbeef;
4622 hr = IPropertyStore_GetCount(store, &count);
4623 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4624 ok(!count, "Unexpected count %u.\n", count);
4626 hr = IPropertyStore_Commit(store);
4627 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4629 hr = IPropertyStore_GetAt(store, 0, &key);
4630 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4632 hr = IPropertyStore_GetValue(store, NULL, &value);
4633 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4635 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
4636 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4638 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4639 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4641 memset(&value, 0, sizeof(PROPVARIANT));
4642 value.vt = VT_I4;
4643 value.lVal = 0xdeadbeef;
4644 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4645 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4647 if (0)
4649 /* crashes on Windows */
4650 hr = IPropertyStore_SetValue(store, NULL, &value);
4651 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4654 hr = IPropertyStore_GetCount(store, &count);
4655 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4656 ok(count == 1, "Unexpected count %u.\n", count);
4658 hr = IPropertyStore_Commit(store);
4659 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4661 hr = IPropertyStore_GetAt(store, 0, &key);
4662 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4663 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
4665 hr = IPropertyStore_GetAt(store, 1, &key);
4666 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4668 memset(&value, 0xcc, sizeof(PROPVARIANT));
4669 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4670 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4671 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
4672 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
4674 memset(&value, 0, sizeof(PROPVARIANT));
4675 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4676 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4678 hr = IPropertyStore_GetCount(store, &count);
4679 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4680 ok(count == 1, "Unexpected count %u.\n", count);
4682 memset(&value, 0xcc, sizeof(PROPVARIANT));
4683 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4684 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4685 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
4686 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
4688 refcount = IPropertyStore_Release(store);
4689 ok(!refcount, "Unexpected refcount %u.\n", refcount);
4692 struct test_thread_param
4694 IMFDXGIDeviceManager *manager;
4695 HANDLE handle;
4696 BOOL lock;
4699 static DWORD WINAPI test_device_manager_thread(void *arg)
4701 struct test_thread_param *param = arg;
4702 ID3D11Device *device;
4703 HRESULT hr;
4705 if (param->lock)
4707 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
4708 (void **)&device, FALSE);
4709 if (SUCCEEDED(hr))
4710 ID3D11Device_Release(device);
4712 else
4713 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
4715 return hr;
4718 static void test_dxgi_device_manager(void)
4720 IMFDXGIDeviceManager *manager, *manager2;
4721 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
4722 struct test_thread_param param;
4723 HANDLE handle1, handle, thread;
4724 UINT token, token2;
4725 IUnknown *unk;
4726 HRESULT hr;
4728 if (!pMFCreateDXGIDeviceManager)
4730 win_skip("MFCreateDXGIDeviceManager not found.\n");
4731 return;
4734 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
4735 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4737 token = 0;
4738 hr = pMFCreateDXGIDeviceManager(&token, NULL);
4739 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4740 ok(!token, "got wrong token: %u.\n", token);
4742 hr = pMFCreateDXGIDeviceManager(&token, &manager);
4743 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4744 EXPECT_REF(manager, 1);
4745 ok(!!token, "got wrong token: %u.\n", token);
4747 Sleep(50);
4748 token2 = 0;
4749 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
4750 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4751 EXPECT_REF(manager2, 1);
4752 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
4753 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
4754 EXPECT_REF(manager, 1);
4756 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4757 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4759 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4760 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4762 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
4763 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4765 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
4766 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
4767 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4768 EXPECT_REF(d3d11_dev, 1);
4770 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
4771 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4772 EXPECT_REF(d3d11_dev, 1);
4774 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
4775 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4777 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4778 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4779 EXPECT_REF(manager, 1);
4780 EXPECT_REF(d3d11_dev, 2);
4782 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
4783 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4784 EXPECT_REF(manager2, 1);
4785 EXPECT_REF(d3d11_dev, 2);
4787 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4788 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4789 EXPECT_REF(manager, 1);
4790 EXPECT_REF(d3d11_dev, 2);
4792 /* GetVideoService() on device change. */
4793 handle = NULL;
4794 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4795 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4796 ok(!!handle, "Unexpected handle value %p.\n", handle);
4798 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
4799 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
4800 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4801 EXPECT_REF(d3d11_dev2, 1);
4802 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
4803 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4804 EXPECT_REF(manager, 1);
4805 EXPECT_REF(d3d11_dev2, 2);
4806 EXPECT_REF(d3d11_dev, 1);
4808 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4809 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr);
4811 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4812 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4814 handle = NULL;
4815 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4816 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4817 ok(!!handle, "Unexpected handle value %p.\n", handle);
4819 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4820 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4822 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4823 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4824 IUnknown_Release(unk);
4826 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
4827 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4828 IUnknown_Release(unk);
4830 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
4831 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4832 IUnknown_Release(unk);
4834 handle1 = NULL;
4835 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4836 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4837 ok(handle != handle1, "Unexpected handle.\n");
4839 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4840 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4842 /* Already closed. */
4843 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4844 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4846 handle = NULL;
4847 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4848 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4850 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4851 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4853 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
4854 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4856 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4857 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4858 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
4859 ID3D11Device_Release(device);
4861 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4862 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4864 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4865 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4867 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
4868 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4870 /* Locked with one handle, unlock with another. */
4871 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4872 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4874 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4875 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4877 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4878 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4880 ID3D11Device_Release(device);
4882 /* Closing unlocks the device. */
4883 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4884 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4886 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4887 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4888 ID3D11Device_Release(device);
4890 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4891 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4893 /* Open two handles. */
4894 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4895 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4897 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4898 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4900 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4901 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4902 ID3D11Device_Release(device);
4904 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4905 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4906 ID3D11Device_Release(device);
4908 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4909 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4911 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4912 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4914 param.manager = manager;
4915 param.handle = handle;
4916 param.lock = TRUE;
4917 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4918 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4919 GetExitCodeThread(thread, (DWORD *)&hr);
4920 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#x.\n", hr);
4921 CloseHandle(thread);
4923 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4926 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4927 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4929 /* Lock on main thread, unlock on another. */
4930 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4931 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4932 ID3D11Device_Release(device);
4934 param.manager = manager;
4935 param.handle = handle;
4936 param.lock = FALSE;
4937 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4938 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4939 GetExitCodeThread(thread, (DWORD *)&hr);
4940 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4941 CloseHandle(thread);
4943 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4946 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4947 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4949 IMFDXGIDeviceManager_Release(manager);
4950 EXPECT_REF(d3d11_dev2, 1);
4951 ID3D11Device_Release(d3d11_dev);
4952 ID3D11Device_Release(d3d11_dev2);
4953 IMFDXGIDeviceManager_Release(manager2);
4956 static void test_MFCreateTransformActivate(void)
4958 IMFActivate *activate;
4959 UINT32 count;
4960 HRESULT hr;
4962 if (!pMFCreateTransformActivate)
4964 win_skip("MFCreateTransformActivate() is not available.\n");
4965 return;
4968 hr = pMFCreateTransformActivate(&activate);
4969 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
4971 hr = IMFActivate_GetCount(activate, &count);
4972 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4973 ok(!count, "Unexpected attribute count %u.\n", count);
4975 IMFActivate_Release(activate);
4978 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
4980 if (IsEqualIID(riid, &IID_IClassFactory) ||
4981 IsEqualIID(riid, &IID_IUnknown))
4983 *obj = iface;
4984 IClassFactory_AddRef(iface);
4985 return S_OK;
4988 *obj = NULL;
4989 return E_NOINTERFACE;
4992 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
4994 return 2;
4997 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
4999 return 1;
5002 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5004 ok(0, "Unexpected call.\n");
5005 return E_NOTIMPL;
5008 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5010 return S_OK;
5013 static const IClassFactoryVtbl test_mft_factory_vtbl =
5015 test_mft_factory_QueryInterface,
5016 test_mft_factory_AddRef,
5017 test_mft_factory_Release,
5018 test_mft_factory_CreateInstance,
5019 test_mft_factory_LockServer,
5022 static void test_MFTRegisterLocal(void)
5024 IClassFactory test_factory = { &test_mft_factory_vtbl };
5025 MFT_REGISTER_TYPE_INFO input_types[1];
5026 IMFActivate **activate;
5027 UINT32 count, count2;
5028 HRESULT hr;
5030 if (!pMFTRegisterLocal)
5032 win_skip("MFTRegisterLocal() is not available.\n");
5033 return;
5036 input_types[0].guidMajorType = MFMediaType_Audio;
5037 input_types[0].guidSubtype = MFAudioFormat_PCM;
5038 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5039 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5041 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5042 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5044 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5045 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5046 ok(count > 0, "Unexpected count %u.\n", count);
5047 CoTaskMemFree(activate);
5049 hr = pMFTUnregisterLocal(&test_factory);
5050 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
5052 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5053 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5054 ok(count2 < count, "Unexpected count %u.\n", count2);
5055 CoTaskMemFree(activate);
5057 hr = pMFTUnregisterLocal(&test_factory);
5058 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5060 hr = pMFTUnregisterLocal(NULL);
5061 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5063 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5064 0, NULL);
5065 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5067 hr = pMFTUnregisterLocal(NULL);
5068 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5070 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5071 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5073 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5074 0, NULL);
5075 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5077 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5078 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5081 static void test_queue_com(void)
5083 static int system_queues[] =
5085 MFASYNC_CALLBACK_QUEUE_STANDARD,
5086 MFASYNC_CALLBACK_QUEUE_RT,
5087 MFASYNC_CALLBACK_QUEUE_IO,
5088 MFASYNC_CALLBACK_QUEUE_TIMER,
5089 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5090 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5093 static int user_queues[] =
5095 MF_STANDARD_WORKQUEUE,
5096 MF_WINDOW_WORKQUEUE,
5097 MF_MULTITHREADED_WORKQUEUE,
5100 char path_name[MAX_PATH];
5101 PROCESS_INFORMATION info;
5102 STARTUPINFOA startup;
5103 char **argv;
5104 int i;
5106 if (!pCoGetApartmentType)
5108 win_skip("CoGetApartmentType() is not available.\n");
5109 return;
5112 winetest_get_mainargs(&argv);
5114 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5116 memset(&startup, 0, sizeof(startup));
5117 startup.cb = sizeof(startup);
5118 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5119 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5120 "CreateProcess failed.\n" );
5121 wait_child_process(info.hProcess);
5122 CloseHandle(info.hProcess);
5123 CloseHandle(info.hThread);
5126 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5128 memset(&startup, 0, sizeof(startup));
5129 startup.cb = sizeof(startup);
5130 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5131 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5132 "CreateProcess failed.\n" );
5133 wait_child_process(info.hProcess);
5134 CloseHandle(info.hProcess);
5135 CloseHandle(info.hThread);
5139 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5141 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5142 APTTYPEQUALIFIER qualifier;
5143 APTTYPE com_type;
5144 HRESULT hr;
5146 hr = pCoGetApartmentType(&com_type, &qualifier);
5147 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr);
5148 if (SUCCEEDED(hr))
5150 todo_wine {
5151 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5152 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5153 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5154 else
5155 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5156 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5160 SetEvent(callback->event);
5161 return S_OK;
5164 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5166 testcallback_QueryInterface,
5167 testcallback_AddRef,
5168 testcallback_Release,
5169 testcallback_GetParameters,
5170 test_queue_com_state_callback_Invoke,
5173 static void test_queue_com_state(const char *name)
5175 struct test_callback callback = { { &test_queue_com_state_callback_vtbl } };
5176 DWORD queue, queue_type;
5177 HRESULT hr;
5179 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
5181 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5182 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
5184 if (name[0] == 's')
5186 callback.param = name[1] - '0';
5187 hr = MFPutWorkItem(callback.param, &callback.IMFAsyncCallback_iface, NULL);
5188 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5189 WaitForSingleObject(callback.event, INFINITE);
5191 else if (name[0] == 'u')
5193 queue_type = name[1] - '0';
5195 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5196 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5197 "Failed to allocate a queue of type %u, hr %#x.\n", queue_type, hr);
5199 if (SUCCEEDED(hr))
5201 callback.param = queue;
5202 hr = MFPutWorkItem(queue, &callback.IMFAsyncCallback_iface, NULL);
5203 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5204 WaitForSingleObject(callback.event, INFINITE);
5206 hr = MFUnlockWorkQueue(queue);
5207 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
5211 CloseHandle(callback.event);
5213 hr = MFShutdown();
5214 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
5217 static void test_MFGetStrideForBitmapInfoHeader(void)
5219 static const struct stride_test
5221 const GUID *subtype;
5222 unsigned int width;
5223 LONG stride;
5225 stride_tests[] =
5227 { &MFVideoFormat_RGB8, 3, -4 },
5228 { &MFVideoFormat_RGB8, 1, -4 },
5229 { &MFVideoFormat_RGB555, 3, -8 },
5230 { &MFVideoFormat_RGB555, 1, -4 },
5231 { &MFVideoFormat_RGB565, 3, -8 },
5232 { &MFVideoFormat_RGB565, 1, -4 },
5233 { &MFVideoFormat_RGB24, 3, -12 },
5234 { &MFVideoFormat_RGB24, 1, -4 },
5235 { &MFVideoFormat_RGB32, 3, -12 },
5236 { &MFVideoFormat_RGB32, 1, -4 },
5237 { &MFVideoFormat_ARGB32, 3, -12 },
5238 { &MFVideoFormat_ARGB32, 1, -4 },
5239 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5240 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5241 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5242 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5244 /* YUV */
5245 { &MFVideoFormat_NV12, 1, 1 },
5246 { &MFVideoFormat_NV12, 2, 2 },
5247 { &MFVideoFormat_NV12, 3, 3 },
5248 { &MFVideoFormat_AYUV, 1, 4 },
5249 { &MFVideoFormat_AYUV, 4, 16 },
5250 { &MFVideoFormat_AYUV, 5, 20 },
5251 { &MFVideoFormat_IMC1, 1, 4 },
5252 { &MFVideoFormat_IMC1, 2, 4 },
5253 { &MFVideoFormat_IMC1, 3, 8 },
5254 { &MFVideoFormat_IMC3, 1, 4 },
5255 { &MFVideoFormat_IMC3, 2, 4 },
5256 { &MFVideoFormat_IMC3, 3, 8 },
5257 { &MFVideoFormat_IMC2, 1, 1 },
5258 { &MFVideoFormat_IMC2, 2, 2 },
5259 { &MFVideoFormat_IMC2, 3, 3 },
5260 { &MFVideoFormat_IMC4, 1, 1 },
5261 { &MFVideoFormat_IMC4, 2, 2 },
5262 { &MFVideoFormat_IMC4, 3, 3 },
5263 { &MFVideoFormat_YV12, 1, 1 },
5264 { &MFVideoFormat_YV12, 2, 2 },
5265 { &MFVideoFormat_YV12, 3, 3 },
5266 { &MFVideoFormat_YV12, 320, 320 },
5267 { &MFVideoFormat_I420, 1, 1 },
5268 { &MFVideoFormat_I420, 2, 2 },
5269 { &MFVideoFormat_I420, 3, 3 },
5270 { &MFVideoFormat_I420, 320, 320 },
5272 unsigned int i;
5273 LONG stride;
5274 HRESULT hr;
5276 if (!pMFGetStrideForBitmapInfoHeader)
5278 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5279 return;
5282 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5283 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5285 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5287 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5288 ok(hr == S_OK, "%u: failed to get stride, hr %#x.\n", i, hr);
5289 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %d, expected %d.\n", i,
5290 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5294 static void test_MFCreate2DMediaBuffer(void)
5296 static const struct _2d_buffer_test
5298 unsigned int width;
5299 unsigned int height;
5300 unsigned int fourcc;
5301 unsigned int contiguous_length;
5302 int pitch;
5303 unsigned int plane_multiplier;
5304 } _2d_buffer_tests[] =
5306 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64 },
5307 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5308 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5309 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5311 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128 },
5312 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5313 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5314 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5315 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5316 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5318 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128, 2 },
5319 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128, 2 },
5320 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 2 },
5321 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128, 2 },
5323 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128, 2 },
5324 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128, 2 },
5325 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 2 },
5326 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128, 2 },
5328 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5329 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5330 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128 },
5332 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5333 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5334 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64 },
5336 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5337 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5338 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64 },
5340 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5341 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5342 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64 },
5344 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5345 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5346 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5348 unsigned int max_length, length, length2;
5349 BYTE *buffer_start, *data, *data2;
5350 IMF2DBuffer2 *_2dbuffer2;
5351 IMF2DBuffer *_2dbuffer;
5352 IMFMediaBuffer *buffer;
5353 int i, pitch, pitch2;
5354 HRESULT hr;
5355 BOOL ret;
5357 if (!pMFCreate2DMediaBuffer)
5359 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5360 return;
5363 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5364 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5366 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5367 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5369 /* YUV formats can't be bottom-up. */
5370 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5371 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5373 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5374 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5376 check_interface(buffer, &IID_IMFGetService, TRUE);
5377 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5379 /* Full backing buffer size, with 64 bytes per row alignment. */
5380 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5381 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5382 ok(max_length > 0, "Unexpected length %u.\n", max_length);
5384 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5385 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5386 ok(!length, "Unexpected length.\n");
5388 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5389 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
5391 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5392 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5393 ok(length == 10, "Unexpected length.\n");
5395 /* Linear lock/unlock. */
5397 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5398 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5400 /* Linear locking call returns plane size.*/
5401 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5402 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5403 ok(max_length == length, "Unexpected length.\n");
5405 length = 0;
5406 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5407 ok(max_length == length && length == 9, "Unexpected length %u.\n", length);
5409 /* Already locked */
5410 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5411 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5412 ok(data2 == data, "Unexpected pointer.\n");
5414 hr = IMFMediaBuffer_Unlock(buffer);
5415 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5417 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5418 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5420 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5421 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5423 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5424 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5425 ok(length == 9, "Unexpected length %u.\n", length);
5427 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5428 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5430 /* 2D lock. */
5431 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5432 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
5434 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5435 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5437 hr = IMFMediaBuffer_Unlock(buffer);
5438 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5440 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5441 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5443 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5444 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5446 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5447 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5449 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5450 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5452 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5453 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5454 ok(!!data, "Expected data pointer.\n");
5455 ok(pitch == 64, "Unexpected pitch %d.\n", pitch);
5457 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5458 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5459 ok(data == data2, "Expected data pointer.\n");
5461 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5462 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5464 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5465 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5467 /* Active 2D lock */
5468 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5469 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5471 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5472 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5474 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5475 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5477 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5478 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5480 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5481 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5483 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5484 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#x.\n", hr);
5486 if (SUCCEEDED(hr))
5488 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5489 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5491 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5492 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5494 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5495 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5497 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5498 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5500 /* Flags are ignored. */
5501 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5502 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5504 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5505 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5507 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5508 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5510 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5511 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5513 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5514 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5516 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5517 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5519 IMF2DBuffer2_Release(_2dbuffer2);
5521 else
5522 win_skip("IMF2DBuffer2 is not supported.\n");
5524 IMF2DBuffer_Release(_2dbuffer);
5526 IMFMediaBuffer_Release(buffer);
5528 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5530 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5532 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5533 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5535 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5536 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5538 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5539 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5540 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %u for %u x %u, format %s.\n",
5541 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5543 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5544 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5545 ok(length == ptr->contiguous_length, "%d: unexpected linear buffer length %u for %u x %u, format %s.\n",
5546 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5548 hr = IMFMediaBuffer_Unlock(buffer);
5549 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5551 hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2);
5552 ok(hr == S_OK, "Failed to get plane size, hr %#x.\n", hr);
5553 if (ptr->plane_multiplier)
5554 length2 *= ptr->plane_multiplier;
5555 ok(length2 == length, "%d: contiguous length %u does not match plane size %u, %u x %u, format %s.\n", i, length,
5556 length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5558 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5559 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5561 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
5562 ok(hr == S_OK, "Failed to get scanline, hr %#x.\n", hr);
5563 ok(data2 == data, "Unexpected data pointer.\n");
5564 ok(pitch == pitch2, "Unexpected pitch.\n");
5566 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5567 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5569 ok(pitch == ptr->pitch, "%d: unexpected pitch %d, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
5570 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5572 ret = TRUE;
5573 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
5574 ok(hr == S_OK, "Failed to get format flag, hr %#x.\n", hr);
5575 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
5577 IMF2DBuffer_Release(_2dbuffer);
5579 IMFMediaBuffer_Release(buffer);
5583 static void test_MFCreateMediaBufferFromMediaType(void)
5585 static struct audio_buffer_test
5587 unsigned int duration;
5588 unsigned int min_length;
5589 unsigned int min_alignment;
5590 unsigned int block_alignment;
5591 unsigned int bytes_per_second;
5592 unsigned int buffer_length;
5593 } audio_tests[] =
5595 { 0, 0, 0, 4, 0, 20 },
5596 { 0, 16, 0, 4, 0, 20 },
5597 { 0, 0, 32, 4, 0, 36 },
5598 { 0, 64, 32, 4, 0, 64 },
5599 { 1, 0, 0, 4, 16, 36 },
5600 { 2, 0, 0, 4, 16, 52 },
5602 IMFMediaBuffer *buffer;
5603 UINT32 length;
5604 HRESULT hr;
5605 IMFMediaType *media_type;
5606 unsigned int i;
5608 if (!pMFCreateMediaBufferFromMediaType)
5610 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
5611 return;
5614 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
5615 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5617 hr = MFCreateMediaType(&media_type);
5618 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5620 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
5621 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5623 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
5625 const struct audio_buffer_test *ptr = &audio_tests[i];
5627 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
5628 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5630 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
5631 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5633 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
5634 ptr->min_alignment, &buffer);
5635 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr);
5636 if (FAILED(hr))
5637 break;
5639 check_interface(buffer, &IID_IMFGetService, FALSE);
5641 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5642 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5643 ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
5645 IMFMediaBuffer_Release(buffer);
5648 IMFMediaType_Release(media_type);
5651 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
5653 GUID guid, subtype;
5654 UINT32 value;
5655 HRESULT hr;
5657 hr = IMFMediaType_GetMajorType(mediatype, &guid);
5658 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
5659 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
5661 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
5662 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
5664 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
5666 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
5667 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5669 if (fex->dwChannelMask)
5671 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
5672 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5673 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
5676 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
5678 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
5679 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5680 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
5683 else
5685 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
5686 subtype.Data1 = format->wFormatTag;
5687 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5689 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
5690 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5691 ok(value, "Unexpected value.\n");
5694 if (format->nChannels)
5696 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
5697 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5698 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
5701 if (format->nSamplesPerSec)
5703 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
5704 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5705 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
5708 if (format->nAvgBytesPerSec)
5710 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
5711 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5712 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
5715 if (format->nBlockAlign)
5717 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
5718 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5719 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
5722 if (format->wBitsPerSample)
5724 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
5725 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5726 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
5729 /* Only set for uncompressed formats. */
5730 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
5731 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
5732 IsEqualGUID(&guid, &MFAudioFormat_PCM))
5734 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5735 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
5737 else
5738 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
5741 static void test_MFInitMediaTypeFromWaveFormatEx(void)
5743 static const WAVEFORMATEX waveformatex_tests[] =
5745 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
5746 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
5747 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
5748 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
5749 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
5750 { 1234, 0, 0, 0, 0, 0 },
5751 { WAVE_FORMAT_ALAW },
5752 { WAVE_FORMAT_CREATIVE_ADPCM },
5753 { WAVE_FORMAT_MPEGLAYER3 },
5754 { WAVE_FORMAT_MPEG_ADTS_AAC },
5755 { WAVE_FORMAT_ALAC },
5756 { WAVE_FORMAT_AMR_NB },
5757 { WAVE_FORMAT_AMR_WB },
5758 { WAVE_FORMAT_AMR_WP },
5759 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
5760 { WAVE_FORMAT_DRM },
5761 { WAVE_FORMAT_DTS },
5762 { WAVE_FORMAT_FLAC },
5763 { WAVE_FORMAT_MPEG },
5764 { WAVE_FORMAT_WMAVOICE9 },
5765 { WAVE_FORMAT_OPUS },
5766 { WAVE_FORMAT_WMAUDIO2 },
5767 { WAVE_FORMAT_WMAUDIO3 },
5768 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
5769 { WAVE_FORMAT_WMASPDIF },
5772 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
5773 WAVEFORMATEXTENSIBLE waveformatext;
5774 MPEGLAYER3WAVEFORMAT mp3format;
5775 IMFMediaType *mediatype;
5776 unsigned int i, size;
5777 HRESULT hr;
5779 hr = MFCreateMediaType(&mediatype);
5780 ok(hr == S_OK, "Failed to create mediatype, hr %#x.\n", hr);
5782 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
5784 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
5785 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#x.\n", i, waveformatex_tests[i].wFormatTag, hr);
5787 validate_media_type(mediatype, &waveformatex_tests[i]);
5789 waveformatext.Format = waveformatex_tests[i];
5790 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
5791 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
5792 waveformatext.Samples.wSamplesPerBlock = 123;
5793 waveformatext.dwChannelMask = 0x8;
5794 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
5795 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
5797 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
5798 ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr);
5800 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
5801 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
5803 validate_media_type(mediatype, &waveformatext.Format);
5806 /* MPEGLAYER3WAVEFORMAT */
5807 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
5808 mp3format.wfx.nChannels = 2;
5809 mp3format.wfx.nSamplesPerSec = 44100;
5810 mp3format.wfx.nAvgBytesPerSec = 16000;
5811 mp3format.wfx.nBlockAlign = 1;
5812 mp3format.wfx.wBitsPerSample = 0;
5813 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
5814 mp3format.wID = MPEGLAYER3_ID_MPEG;
5815 mp3format.fdwFlags = 0;
5816 mp3format.nBlockSize = 417;
5817 mp3format.nFramesPerBlock = 0;
5818 mp3format.nCodecDelay = 0;
5820 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
5821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5823 validate_media_type(mediatype, &mp3format.wfx);
5824 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
5825 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5826 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
5827 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
5829 IMFMediaType_Release(mediatype);
5832 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
5834 MFVIDEOFORMAT *video_format;
5835 IMFMediaType *media_type;
5836 UINT32 size;
5837 HRESULT hr;
5839 hr = MFCreateMediaType(&media_type);
5840 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5842 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
5843 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5844 ok(!!video_format, "Unexpected format.\n");
5845 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
5846 CoTaskMemFree(video_format);
5848 IMFMediaType_Release(media_type);
5851 static void test_MFCreateDXSurfaceBuffer(void)
5853 IDirect3DSurface9 *backbuffer = NULL, *surface;
5854 IDirect3DSwapChain9 *swapchain;
5855 DWORD length, max_length;
5856 IDirect3DDevice9 *device;
5857 IMF2DBuffer2 *_2dbuffer2;
5858 IMFMediaBuffer *buffer;
5859 IMF2DBuffer *_2dbuffer;
5860 BYTE *data, *data2;
5861 IMFGetService *gs;
5862 IDirect3D9 *d3d;
5863 HWND window;
5864 HRESULT hr;
5865 LONG pitch;
5866 BOOL value;
5868 if (!pMFCreateDXSurfaceBuffer)
5870 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
5871 return;
5874 window = create_window();
5875 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5876 ok(!!d3d, "Failed to create a D3D object.\n");
5877 if (!(device = create_device(d3d, window)))
5879 skip("Failed to create a D3D device, skipping tests.\n");
5880 goto done;
5883 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
5884 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
5886 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5887 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
5888 ok(backbuffer != NULL, "The back buffer is NULL\n");
5890 IDirect3DSwapChain9_Release(swapchain);
5892 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
5893 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5895 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
5896 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5898 /* Surface is accessible. */
5899 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
5900 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5901 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
5902 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5903 ok(surface == backbuffer, "Unexpected surface pointer.\n");
5904 IDirect3DSurface9_Release(surface);
5905 IMFGetService_Release(gs);
5907 max_length = 0;
5908 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5909 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5910 ok(!!max_length, "Unexpected length %u.\n", max_length);
5912 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5913 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5914 ok(!length, "Unexpected length %u.\n", length);
5916 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
5917 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5919 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5920 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5921 ok(length == 2 * max_length, "Unexpected length %u.\n", length);
5923 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
5924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5925 ok(length == max_length, "Unexpected length.\n");
5927 /* Unlock twice. */
5928 hr = IMFMediaBuffer_Unlock(buffer);
5929 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5931 hr = IMFMediaBuffer_Unlock(buffer);
5932 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5934 /* Lock twice. */
5935 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5936 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5938 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5939 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5940 ok(data == data2, "Unexpected pointer.\n");
5942 hr = IMFMediaBuffer_Unlock(buffer);
5943 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5945 hr = IMFMediaBuffer_Unlock(buffer);
5946 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5948 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5949 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5951 /* Unlocked. */
5952 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5953 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5955 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5956 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5958 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5959 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5961 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5962 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5964 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5965 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5967 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5968 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5970 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5971 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5973 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5974 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5976 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
5977 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5978 ok(!value, "Unexpected return value %d.\n", value);
5980 IMF2DBuffer_Release(_2dbuffer);
5982 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5983 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5985 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
5986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5987 ok(data == data2, "Unexpected scanline pointer.\n");
5988 memset(data, 0xab, 4);
5989 IMF2DBuffer2_Unlock2D(_2dbuffer2);
5991 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
5992 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5993 ok(data[0] == 0xab, "Unexpected leading byte.\n");
5994 IMF2DBuffer2_Unlock2D(_2dbuffer2);
5996 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5997 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5998 ok(data[0] == 0xab, "Unexpected leading byte.\n");
5999 hr = IMFMediaBuffer_Unlock(buffer);
6000 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6002 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6003 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6004 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6006 IMF2DBuffer2_Release(_2dbuffer2);
6008 IMFMediaBuffer_Release(buffer);
6010 done:
6011 if (backbuffer)
6012 IDirect3DSurface9_Release(backbuffer);
6013 IDirect3D9_Release(d3d);
6014 DestroyWindow(window);
6017 static void test_MFCreateTrackedSample(void)
6019 IMFTrackedSample *tracked_sample;
6020 IMFSample *sample;
6021 IUnknown *unk;
6022 HRESULT hr;
6024 if (!pMFCreateTrackedSample)
6026 win_skip("MFCreateTrackedSample() is not available.\n");
6027 return;
6030 hr = pMFCreateTrackedSample(&tracked_sample);
6031 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6033 /* It's actually a sample. */
6034 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6035 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6037 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6038 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6039 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6040 IUnknown_Release(unk);
6042 IMFSample_Release(sample);
6044 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6046 IMFTrackedSample_Release(tracked_sample);
6049 static void test_MFFrameRateToAverageTimePerFrame(void)
6051 static const struct frame_rate_test
6053 unsigned int numerator;
6054 unsigned int denominator;
6055 UINT64 avgtime;
6056 } frame_rate_tests[] =
6058 { 60000, 1001, 166833 },
6059 { 30000, 1001, 333667 },
6060 { 24000, 1001, 417188 },
6061 { 60, 1, 166667 },
6062 { 30, 1, 333333 },
6063 { 50, 1, 200000 },
6064 { 25, 1, 400000 },
6065 { 24, 1, 416667 },
6067 { 39, 1, 256410 },
6068 { 120, 1, 83333 },
6070 unsigned int i;
6071 UINT64 avgtime;
6072 HRESULT hr;
6074 avgtime = 1;
6075 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6076 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6077 ok(!avgtime, "Unexpected frame time.\n");
6079 avgtime = 1;
6080 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6081 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6082 ok(!avgtime, "Unexpected frame time.\n");
6084 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6086 avgtime = 0;
6087 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6088 frame_rate_tests[i].denominator, &avgtime);
6089 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6090 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6091 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6095 static void test_MFMapDXGIFormatToDX9Format(void)
6097 static const struct format_pair
6099 DXGI_FORMAT dxgi_format;
6100 DWORD d3d9_format;
6102 formats_map[] =
6104 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6105 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6106 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6107 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6108 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6109 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6110 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6111 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6112 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6113 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6114 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6115 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6116 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6117 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6118 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6119 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6120 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6121 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6122 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6123 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6124 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6125 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6126 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6127 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6128 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6129 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6130 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6131 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6132 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6133 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6134 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6135 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6136 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6137 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6138 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6139 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6140 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6141 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6142 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6143 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6144 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6145 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6146 { DXGI_FORMAT_P8, D3DFMT_P8 },
6147 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6149 unsigned int i;
6150 DWORD format;
6152 if (!pMFMapDXGIFormatToDX9Format)
6154 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6155 return;
6158 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6160 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6161 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#x, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6165 static void test_MFMapDX9FormatToDXGIFormat(void)
6167 static const struct format_pair
6169 DXGI_FORMAT dxgi_format;
6170 DWORD d3d9_format;
6172 formats_map[] =
6174 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6175 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6176 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6177 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6178 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6179 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6180 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6181 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6182 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6183 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6184 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6185 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6186 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6187 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6188 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6189 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6190 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6191 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6192 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6193 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6194 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6195 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6196 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6197 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6198 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6199 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6200 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6201 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6202 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6203 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6204 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6205 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6206 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6207 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6208 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6209 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6210 { DXGI_FORMAT_P8, D3DFMT_P8 },
6211 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6213 DXGI_FORMAT format;
6214 unsigned int i;
6216 if (!pMFMapDX9FormatToDXGIFormat)
6218 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6219 return;
6222 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6224 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6225 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#x.\n",
6226 format, formats_map[i].d3d9_format);
6230 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6231 REFIID riid, void **obj)
6233 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6234 IsEqualIID(riid, &IID_IUnknown))
6236 *obj = iface;
6237 IMFVideoSampleAllocatorNotify_AddRef(iface);
6238 return S_OK;
6241 *obj = NULL;
6242 return E_NOINTERFACE;
6245 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6247 return 2;
6250 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6252 return 1;
6255 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6257 return E_NOTIMPL;
6260 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6262 test_notify_callback_QueryInterface,
6263 test_notify_callback_AddRef,
6264 test_notify_callback_Release,
6265 test_notify_callback_NotifyRelease,
6268 static IMFMediaType * create_video_type(const GUID *subtype)
6270 IMFMediaType *video_type;
6271 HRESULT hr;
6273 hr = MFCreateMediaType(&video_type);
6274 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6276 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6277 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6279 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6280 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6282 return video_type;
6285 static ID3D11Device *create_d3d11_device(void)
6287 static const D3D_FEATURE_LEVEL default_feature_level[] =
6289 D3D_FEATURE_LEVEL_11_0,
6290 D3D_FEATURE_LEVEL_10_1,
6291 D3D_FEATURE_LEVEL_10_0,
6293 const D3D_FEATURE_LEVEL *feature_level;
6294 unsigned int feature_level_count;
6295 ID3D11Device *device;
6297 feature_level = default_feature_level;
6298 feature_level_count = ARRAY_SIZE(default_feature_level);
6300 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6301 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6302 return device;
6303 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6304 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6305 return device;
6306 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6307 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6308 return device;
6310 return NULL;
6313 static void test_dxgi_surface_buffer(void)
6315 DWORD max_length, cur_length, length, color;
6316 IMFDXGIBuffer *dxgi_buffer;
6317 D3D11_TEXTURE2D_DESC desc;
6318 ID3D11Texture2D *texture;
6319 IMF2DBuffer *_2d_buffer;
6320 IMFMediaBuffer *buffer;
6321 ID3D11Device *device;
6322 UINT index, size;
6323 IUnknown *obj;
6324 HRESULT hr;
6325 BYTE *data;
6327 if (!pMFCreateDXGISurfaceBuffer)
6329 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
6330 return;
6333 device = create_d3d11_device();
6335 memset(&desc, 0, sizeof(desc));
6336 desc.Width = 64;
6337 desc.Height = 64;
6338 desc.ArraySize = 1;
6339 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
6340 desc.SampleDesc.Count = 1;
6341 desc.SampleDesc.Quality = 0;
6343 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6344 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6346 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
6347 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6349 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6350 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6351 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6352 check_interface(buffer, &IID_IMFGetService, FALSE);
6354 max_length = 0;
6355 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6356 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6357 ok(!!max_length, "Unexpected length %u.\n", max_length);
6359 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6360 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6361 ok(!cur_length, "Unexpected length %u.\n", cur_length);
6363 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6364 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6366 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6367 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6368 ok(cur_length == 2 * max_length, "Unexpected length %u.\n", cur_length);
6370 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6371 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6373 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
6374 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6375 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
6376 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6377 ok(length == max_length, "Unexpected length %u.\n", length);
6378 IMF2DBuffer_Release(_2d_buffer);
6380 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6381 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6383 EXPECT_REF(texture, 2);
6384 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
6385 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6386 EXPECT_REF(texture, 3);
6387 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
6388 IUnknown_Release(obj);
6390 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
6391 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6393 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
6394 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6395 ok(index == 0, "Unexpected subresource index.\n");
6397 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6398 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6400 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6401 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6403 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6404 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#x.\n", hr);
6406 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
6407 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6409 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
6410 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6411 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
6412 IUnknown_Release(obj);
6414 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6415 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6417 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
6418 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6420 IMFDXGIBuffer_Release(dxgi_buffer);
6422 /* Texture updates. */
6423 color = get_d3d11_texture_color(texture, 0, 0);
6424 ok(!color, "Unexpected texture color %#x.\n", color);
6426 max_length = cur_length = 0;
6427 data = NULL;
6428 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6429 todo_wine {
6430 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6431 ok(max_length && max_length == cur_length, "Unexpected length %u.\n", max_length);
6433 if (data) *(DWORD *)data = ~0u;
6435 color = get_d3d11_texture_color(texture, 0, 0);
6436 ok(!color, "Unexpected texture color %#x.\n", color);
6438 hr = IMFMediaBuffer_Unlock(buffer);
6439 todo_wine
6440 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6442 color = get_d3d11_texture_color(texture, 0, 0);
6443 todo_wine
6444 ok(color == ~0u, "Unexpected texture color %#x.\n", color);
6446 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6447 todo_wine
6448 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6449 if (SUCCEEDED(hr))
6450 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data);
6452 hr = IMFMediaBuffer_Unlock(buffer);
6453 todo_wine
6454 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6456 IMFMediaBuffer_Release(buffer);
6458 ID3D11Texture2D_Release(texture);
6460 ID3D11Device_Release(device);
6463 static void test_sample_allocator(void)
6465 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
6466 IMFMediaType *media_type, *video_type, *video_type2;
6467 IMFVideoSampleAllocatorCallback *allocator_cb;
6468 IMFVideoSampleAllocatorEx *allocatorex;
6469 IDirect3DDeviceManager9 *d3d9_manager;
6470 IMFVideoSampleAllocator *allocator;
6471 unsigned int i, buffer_count, token;
6472 IDirect3DDevice9 *d3d9_device;
6473 IMFDXGIDeviceManager *manager;
6474 IMFSample *sample, *sample2;
6475 IMFDXGIBuffer *dxgi_buffer;
6476 IMFAttributes *attributes;
6477 D3D11_TEXTURE2D_DESC desc;
6478 ID3D11Texture2D *texture;
6479 IMFMediaBuffer *buffer;
6480 ID3D11Device *device;
6481 LONG refcount, count;
6482 IDirect3D9 *d3d9;
6483 IUnknown *unk;
6484 HRESULT hr;
6485 BYTE *data;
6486 HWND window;
6487 static const unsigned int usage[] =
6489 D3D11_USAGE_DEFAULT,
6490 D3D11_USAGE_IMMUTABLE,
6491 D3D11_USAGE_DYNAMIC,
6492 D3D11_USAGE_STAGING,
6493 D3D11_USAGE_STAGING + 1,
6496 if (!pMFCreateVideoSampleAllocatorEx)
6498 win_skip("MFCreateVideoSampleAllocatorEx() is not available.\n");
6499 return;
6502 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
6503 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6505 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
6506 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
6507 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
6509 IUnknown_Release(unk);
6511 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6512 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6514 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6515 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6517 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6518 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6520 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
6521 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6523 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6524 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6526 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
6527 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6529 count = 10;
6530 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6531 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6532 ok(!count, "Unexpected count %d.\n", count);
6534 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6535 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6537 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6538 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6540 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
6541 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6543 hr = MFCreateMediaType(&media_type);
6544 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6546 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
6547 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6549 video_type = create_video_type(&MFVideoFormat_RGB32);
6550 video_type2 = create_video_type(&MFVideoFormat_RGB32);
6552 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6553 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6555 /* Frame size is required. */
6556 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6557 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6559 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6560 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6562 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6563 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6565 EXPECT_REF(video_type, 1);
6566 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6567 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6568 EXPECT_REF(video_type, 2);
6570 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
6571 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6573 /* Setting identical type does not replace it. */
6574 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6575 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6576 EXPECT_REF(video_type, 2);
6577 EXPECT_REF(video_type2, 1);
6579 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
6580 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6582 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6583 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6584 EXPECT_REF(video_type2, 2);
6585 EXPECT_REF(video_type, 1);
6587 /* Modify referenced type. */
6588 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
6589 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6591 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6592 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6593 EXPECT_REF(video_type, 2);
6594 EXPECT_REF(video_type2, 1);
6596 count = 0;
6597 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6598 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6599 ok(count == 1, "Unexpected count %d.\n", count);
6601 sample = NULL;
6602 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6603 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6604 refcount = get_refcount(sample);
6606 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6607 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6608 ok(!count, "Unexpected count %d.\n", count);
6610 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
6611 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6613 /* Reinitialize with active sample. */
6614 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6615 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6616 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
6617 EXPECT_REF(video_type, 2);
6619 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6620 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6621 todo_wine
6622 ok(!count, "Unexpected count %d.\n", count);
6624 check_interface(sample, &IID_IMFTrackedSample, TRUE);
6625 check_interface(sample, &IID_IMFDesiredSample, FALSE);
6627 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6628 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6630 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6631 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6632 check_interface(buffer, &IID_IMFGetService, TRUE);
6633 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
6635 IMFMediaBuffer_Release(buffer);
6637 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6638 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6639 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
6641 IMFSample_Release(sample);
6643 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6644 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6645 todo_wine
6646 EXPECT_REF(video_type, 2);
6648 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6649 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6650 ok(!count, "Unexpected count %d.\n", count);
6652 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6653 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6655 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6656 IMFVideoSampleAllocator_Release(allocator);
6658 /* IMFVideoSampleAllocatorEx */
6659 hr = MFCreateAttributes(&attributes, 0);
6660 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6662 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6663 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6665 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6666 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6668 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
6669 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6671 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
6672 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6674 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6675 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6677 EXPECT_REF(attributes, 1);
6678 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6679 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6680 EXPECT_REF(attributes, 2);
6682 count = 0;
6683 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6684 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6685 ok(count == 1, "Unexpected count %d.\n", count);
6687 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6688 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6690 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6691 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6692 ok(buffer_count == 2, "Unexpected buffer count %u.\n", buffer_count);
6694 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6695 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6697 /* Reinitialize with already allocated samples. */
6698 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
6699 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6700 EXPECT_REF(attributes, 1);
6702 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6703 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6704 IMFSample_Release(sample2);
6706 IMFSample_Release(sample);
6708 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6709 IMFVideoSampleAllocatorEx_Release(allocatorex);
6710 IMFAttributes_Release(attributes);
6712 /* Using device manager */
6713 if (!(device = create_d3d11_device()))
6715 skip("Failed to create a D3D11 device, skipping tests.\n");
6716 return;
6719 hr = pMFCreateDXGIDeviceManager(&token, &manager);
6720 ok(hr == S_OK, "Failed to create device manager, hr %#x.\n", hr);
6722 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
6723 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
6725 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6726 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6728 EXPECT_REF(manager, 1);
6729 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
6730 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6731 EXPECT_REF(manager, 2);
6733 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6734 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6736 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6737 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6739 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6740 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6742 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6743 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6745 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6746 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6747 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6748 check_interface(buffer, &IID_IMFGetService, FALSE);
6750 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6751 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6753 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6754 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6756 ID3D11Texture2D_GetDesc(texture, &desc);
6757 ok(desc.Width == 320, "Unexpected width %u.\n", desc.Width);
6758 ok(desc.Height == 240, "Unexpected height %u.\n", desc.Height);
6759 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
6760 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
6761 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
6762 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
6763 ok(desc.SampleDesc.Quality == 0, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
6764 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
6765 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6766 desc.BindFlags);
6767 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6768 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6770 ID3D11Texture2D_Release(texture);
6771 IMFDXGIBuffer_Release(dxgi_buffer);
6773 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6774 todo_wine
6775 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6777 hr = IMFMediaBuffer_Unlock(buffer);
6778 todo_wine
6779 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6781 IMFSample_Release(sample);
6783 IMFVideoSampleAllocator_Release(allocator);
6785 /* MF_SA_D3D11_USAGE */
6786 hr = MFCreateAttributes(&attributes, 1);
6787 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
6789 for (i = 0; i < ARRAY_SIZE(usage); ++i)
6791 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6792 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6794 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
6795 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6797 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
6798 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6800 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6801 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
6803 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6804 IMFVideoSampleAllocatorEx_Release(allocatorex);
6805 continue;
6807 ok(hr == S_OK, "%u: Unexpected hr %#x.\n", usage[i], hr);
6809 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
6810 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6812 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6815 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6816 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6818 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6819 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6821 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6822 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6824 ID3D11Texture2D_GetDesc(texture, &desc);
6825 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
6826 if (usage[i] == D3D11_USAGE_DEFAULT)
6828 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6829 desc.BindFlags);
6830 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6832 else if (usage[i] == D3D11_USAGE_DYNAMIC)
6834 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
6835 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6837 else if (usage[i] == D3D11_USAGE_STAGING)
6839 ok(desc.BindFlags == 0, "Unexpected bind flags %#x.\n", desc.BindFlags);
6840 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
6841 desc.CPUAccessFlags);
6843 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6845 ID3D11Texture2D_Release(texture);
6846 IMFDXGIBuffer_Release(dxgi_buffer);
6847 IMFMediaBuffer_Release(buffer);
6849 IMFSample_Release(sample);
6851 IMFVideoSampleAllocatorEx_Release(allocatorex);
6854 IMFAttributes_Release(attributes);
6856 IMFDXGIDeviceManager_Release(manager);
6857 ID3D11Device_Release(device);
6859 /* Use D3D9 device manager. */
6860 window = create_window();
6861 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6862 ok(!!d3d9, "Failed to create a D3D9 object.\n");
6863 if (!(d3d9_device = create_device(d3d9, window)))
6865 skip("Failed to create a D3D9 device, skipping tests.\n");
6866 goto done;
6869 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
6870 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6872 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
6873 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6875 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6876 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6878 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
6879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6881 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6884 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6885 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6887 check_interface(sample, &IID_IMFTrackedSample, TRUE);
6888 check_interface(sample, &IID_IMFDesiredSample, FALSE);
6890 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6891 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6893 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6894 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6895 check_interface(buffer, &IID_IMFGetService, TRUE);
6896 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
6898 IMFSample_Release(sample);
6899 IMFMediaBuffer_Release(buffer);
6901 IMFVideoSampleAllocator_Release(allocator);
6902 IMFMediaType_Release(media_type);
6904 done:
6905 IDirect3D9_Release(d3d9);
6906 DestroyWindow(window);
6909 START_TEST(mfplat)
6911 char **argv;
6912 int argc;
6914 init_functions();
6916 argc = winetest_get_mainargs(&argv);
6917 if (argc >= 3)
6919 test_queue_com_state(argv[2]);
6920 return;
6923 CoInitialize(NULL);
6925 test_startup();
6926 test_register();
6927 test_media_type();
6928 test_MFCreateMediaEvent();
6929 test_attributes();
6930 test_sample();
6931 test_file_stream();
6932 test_MFCreateMFByteStreamOnStream();
6933 test_system_memory_buffer();
6934 test_source_resolver();
6935 test_MFCreateAsyncResult();
6936 test_allocate_queue();
6937 test_MFCopyImage();
6938 test_MFCreateCollection();
6939 test_MFHeapAlloc();
6940 test_scheduled_items();
6941 test_serial_queue();
6942 test_periodic_callback();
6943 test_event_queue();
6944 test_presentation_descriptor();
6945 test_system_time_source();
6946 test_MFInvokeCallback();
6947 test_stream_descriptor();
6948 test_MFCalculateImageSize();
6949 test_MFCompareFullToPartialMediaType();
6950 test_attributes_serialization();
6951 test_wrapped_media_type();
6952 test_MFCreateWaveFormatExFromMFMediaType();
6953 test_async_create_file();
6954 test_local_handlers();
6955 test_create_property_store();
6956 test_dxgi_device_manager();
6957 test_MFCreateTransformActivate();
6958 test_MFTRegisterLocal();
6959 test_queue_com();
6960 test_MFGetStrideForBitmapInfoHeader();
6961 test_MFCreate2DMediaBuffer();
6962 test_MFCreateMediaBufferFromMediaType();
6963 test_MFInitMediaTypeFromWaveFormatEx();
6964 test_MFCreateMFVideoFormatFromMFMediaType();
6965 test_MFCreateDXSurfaceBuffer();
6966 test_MFCreateTrackedSample();
6967 test_MFFrameRateToAverageTimePerFrame();
6968 test_MFMapDXGIFormatToDX9Format();
6969 test_dxgi_surface_buffer();
6970 test_sample_allocator();
6971 test_MFMapDX9FormatToDXGIFormat();
6973 CoUninitialize();