mf/session: Forward more events to the application.
[wine/zf.git] / dlls / mfplat / tests / mfplat.c
blobc33d540ba4be37ea870bca0d78c46c8dd592235c
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 #define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d)
97 static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported)
99 IUnknown *iface = iface_ptr;
100 HRESULT hr, expected_hr;
101 IMFGetService *gs;
102 IUnknown *unk;
104 expected_hr = supported ? S_OK : E_NOINTERFACE;
106 if (SUCCEEDED(hr = IUnknown_QueryInterface(iface, &IID_IMFGetService, (void **)&gs)))
108 hr = IMFGetService_GetService(gs, service, iid, (void **)&unk);
109 IMFGetService_Release(gs);
111 ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
112 if (SUCCEEDED(hr))
113 IUnknown_Release(unk);
116 struct d3d11_resource_readback
118 ID3D11Resource *resource;
119 D3D11_MAPPED_SUBRESOURCE map_desc;
120 ID3D11DeviceContext *immediate_context;
121 unsigned int width, height, depth, sub_resource_idx;
124 static void init_d3d11_resource_readback(ID3D11Resource *resource, ID3D11Resource *readback_resource,
125 unsigned int width, unsigned int height, unsigned int depth, unsigned int sub_resource_idx,
126 ID3D11Device *device, struct d3d11_resource_readback *rb)
128 HRESULT hr;
130 rb->resource = readback_resource;
131 rb->width = width;
132 rb->height = height;
133 rb->depth = depth;
134 rb->sub_resource_idx = sub_resource_idx;
136 ID3D11Device_GetImmediateContext(device, &rb->immediate_context);
138 ID3D11DeviceContext_CopyResource(rb->immediate_context, rb->resource, resource);
139 if (FAILED(hr = ID3D11DeviceContext_Map(rb->immediate_context,
140 rb->resource, sub_resource_idx, D3D11_MAP_READ, 0, &rb->map_desc)))
142 trace("Failed to map resource, hr %#x.\n", hr);
143 ID3D11Resource_Release(rb->resource);
144 rb->resource = NULL;
145 ID3D11DeviceContext_Release(rb->immediate_context);
146 rb->immediate_context = NULL;
150 static void get_d3d11_texture2d_readback(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
151 struct d3d11_resource_readback *rb)
153 D3D11_TEXTURE2D_DESC texture_desc;
154 ID3D11Resource *rb_texture;
155 unsigned int miplevel;
156 ID3D11Device *device;
157 HRESULT hr;
159 memset(rb, 0, sizeof(*rb));
161 ID3D11Texture2D_GetDevice(texture, &device);
163 ID3D11Texture2D_GetDesc(texture, &texture_desc);
164 texture_desc.Usage = D3D11_USAGE_STAGING;
165 texture_desc.BindFlags = 0;
166 texture_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
167 texture_desc.MiscFlags = 0;
168 if (FAILED(hr = ID3D11Device_CreateTexture2D(device, &texture_desc, NULL, (ID3D11Texture2D **)&rb_texture)))
170 trace("Failed to create texture, hr %#x.\n", hr);
171 ID3D11Device_Release(device);
172 return;
175 miplevel = sub_resource_idx % texture_desc.MipLevels;
176 init_d3d11_resource_readback((ID3D11Resource *)texture, rb_texture,
177 max(1, texture_desc.Width >> miplevel),
178 max(1, texture_desc.Height >> miplevel),
179 1, sub_resource_idx, device, rb);
181 ID3D11Device_Release(device);
184 static void release_d3d11_resource_readback(struct d3d11_resource_readback *rb)
186 ID3D11DeviceContext_Unmap(rb->immediate_context, rb->resource, rb->sub_resource_idx);
187 ID3D11Resource_Release(rb->resource);
188 ID3D11DeviceContext_Release(rb->immediate_context);
191 static void *get_d3d11_readback_data(struct d3d11_resource_readback *rb,
192 unsigned int x, unsigned int y, unsigned int z, unsigned byte_width)
194 return (BYTE *)rb->map_desc.pData + z * rb->map_desc.DepthPitch + y * rb->map_desc.RowPitch + x * byte_width;
197 static DWORD get_d3d11_readback_u32(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
199 return *(DWORD *)get_d3d11_readback_data(rb, x, y, z, sizeof(DWORD));
202 static DWORD get_d3d11_readback_color(struct d3d11_resource_readback *rb, unsigned int x, unsigned int y, unsigned int z)
204 return get_d3d11_readback_u32(rb, x, y, z);
207 static DWORD get_d3d11_texture_color(ID3D11Texture2D *texture, unsigned int x, unsigned int y)
209 struct d3d11_resource_readback rb;
210 DWORD color;
212 get_d3d11_texture2d_readback(texture, 0, &rb);
213 color = get_d3d11_readback_color(&rb, x, y, 0);
214 release_d3d11_resource_readback(&rb);
216 return color;
219 static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags,
220 const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out,
221 D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
223 static HRESULT (WINAPI *pCoGetApartmentType)(APTTYPE *type, APTTYPEQUALIFIER *qualifier);
225 static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride,
226 DWORD width, DWORD lines);
227 static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager);
228 static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver);
229 static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream);
230 static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key);
231 static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue);
232 static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key);
233 static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
234 static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime,
235 IMFActivate *activate);
236 static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate);
237 static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
238 static HRESULT (WINAPI *pMFTRegisterLocal)(IClassFactory *factory, REFGUID category, LPCWSTR name,
239 UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput,
240 const MFT_REGISTER_TYPE_INFO* output_types);
241 static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID category, LPCWSTR name, UINT32 flags,
242 UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count,
243 const MFT_REGISTER_TYPE_INFO *output_types);
244 static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory);
245 static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid);
246 static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue);
247 static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type,
248 const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
249 static HRESULT (WINAPI *pMFGetPlaneSize)(DWORD format, DWORD width, DWORD height, DWORD *size);
250 static HRESULT (WINAPI *pMFGetStrideForBitmapInfoHeader)(DWORD format, DWORD width, LONG *stride);
251 static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD fourcc, BOOL bottom_up,
252 IMFMediaBuffer **buffer);
253 static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length,
254 DWORD min_alignment, IMFMediaBuffer **buffer);
255 static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer);
256 static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
257 static DWORD (WINAPI *pMFMapDXGIFormatToDX9Format)(DXGI_FORMAT dxgi_format);
258 static DXGI_FORMAT (WINAPI *pMFMapDX9FormatToDXGIFormat)(DWORD format);
259 static HRESULT (WINAPI *pMFCreateVideoSampleAllocatorEx)(REFIID riid, void **allocator);
260 static HRESULT (WINAPI *pMFCreateDXGISurfaceBuffer)(REFIID riid, IUnknown *surface, UINT subresource, BOOL bottomup,
261 IMFMediaBuffer **buffer);
262 static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **media_type);
263 static HRESULT (WINAPI *pMFLockSharedWorkQueue)(const WCHAR *name, LONG base_priority, DWORD *taskid, DWORD *queue);
265 static HWND create_window(void)
267 RECT r = {0, 0, 640, 480};
269 AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
271 return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
272 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
275 static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window)
277 D3DPRESENT_PARAMETERS present_parameters = {0};
278 IDirect3DDevice9 *device = NULL;
280 present_parameters.BackBufferWidth = 640;
281 present_parameters.BackBufferHeight = 480;
282 present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
283 present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
284 present_parameters.hDeviceWindow = focus_window;
285 present_parameters.Windowed = TRUE;
286 present_parameters.EnableAutoDepthStencil = TRUE;
287 present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
288 present_parameters.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
290 IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
291 D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device);
293 return device;
296 static const WCHAR fileschemeW[] = L"file://";
298 static WCHAR *load_resource(const WCHAR *name)
300 static WCHAR pathW[MAX_PATH];
301 DWORD written;
302 HANDLE file;
303 HRSRC res;
304 void *ptr;
306 GetTempPathW(ARRAY_SIZE(pathW), pathW);
307 lstrcatW(pathW, name);
309 file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
310 NULL, CREATE_ALWAYS, 0, 0);
311 ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
312 wine_dbgstr_w(pathW), GetLastError());
314 res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
315 ok(res != 0, "couldn't find resource\n");
316 ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
317 WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
318 &written, NULL);
319 ok(written == SizeofResource(GetModuleHandleA(NULL), res),
320 "couldn't write resource\n" );
321 CloseHandle(file);
323 return pathW;
326 struct test_callback
328 IMFAsyncCallback IMFAsyncCallback_iface;
329 HANDLE event;
330 DWORD param;
331 IMFMediaEvent *media_event;
334 static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface)
336 return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface);
339 static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj)
341 if (IsEqualIID(riid, &IID_IMFAsyncCallback) ||
342 IsEqualIID(riid, &IID_IUnknown))
344 *obj = iface;
345 IMFAsyncCallback_AddRef(iface);
346 return S_OK;
349 *obj = NULL;
350 return E_NOINTERFACE;
353 static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface)
355 return 2;
358 static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
360 return 1;
363 static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue)
365 ok(flags != NULL && queue != NULL, "Unexpected arguments.\n");
366 return E_NOTIMPL;
370 static BOOL check_clsid(CLSID *clsids, UINT32 count)
372 int i;
373 for (i = 0; i < count; i++)
375 if (IsEqualGUID(&clsids[i], &DUMMY_CLSID))
376 return TRUE;
378 return FALSE;
381 static void test_register(void)
383 WCHAR name[] = L"Wine test";
384 MFT_REGISTER_TYPE_INFO input[] =
386 { DUMMY_CLSID, DUMMY_GUID1 }
388 MFT_REGISTER_TYPE_INFO output[] =
390 { DUMMY_CLSID, DUMMY_GUID2 }
392 CLSID *clsids;
393 UINT32 count;
394 HRESULT ret;
396 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, input, 1, output, NULL);
397 if (ret == E_ACCESSDENIED)
399 win_skip("Not enough permissions to register a filter\n");
400 return;
402 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
404 if(0)
406 /* NULL name crashes on windows */
407 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, NULL, 0, 1, input, 1, output, NULL);
408 ok(ret == E_INVALIDARG, "got %x\n", ret);
411 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 0, NULL, NULL);
412 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
414 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 1, NULL, 0, NULL, NULL);
415 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
417 ret = MFTRegister(DUMMY_CLSID, MFT_CATEGORY_OTHER, name, 0, 0, NULL, 1, NULL, NULL);
418 ok(ret == S_OK, "Failed to register dummy filter: %x\n", ret);
420 if(0)
422 /* NULL clsids/count crashes on windows (vista) */
423 count = 0;
424 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, NULL, &count);
425 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
426 ok(count == 0, "Expected count == 0\n");
428 clsids = NULL;
429 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, NULL);
430 ok(ret == E_POINTER, "Failed to enumerate filters: %x\n", ret);
433 count = 0;
434 clsids = NULL;
435 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, NULL, NULL, &clsids, &count);
436 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
437 ok(count > 0, "Expected count > 0\n");
438 ok(clsids != NULL, "Expected clsids != NULL\n");
439 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
440 CoTaskMemFree(clsids);
442 count = 0;
443 clsids = NULL;
444 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, NULL, NULL, &clsids, &count);
445 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
446 ok(count > 0, "Expected count > 0\n");
447 ok(clsids != NULL, "Expected clsids != NULL\n");
448 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
449 CoTaskMemFree(clsids);
451 count = 0;
452 clsids = NULL;
453 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, NULL, output, NULL, &clsids, &count);
454 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
455 ok(count > 0, "Expected count > 0\n");
456 ok(clsids != NULL, "Expected clsids != NULL\n");
457 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
458 CoTaskMemFree(clsids);
460 count = 0;
461 clsids = NULL;
462 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, input, output, NULL, &clsids, &count);
463 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
464 ok(count > 0, "Expected count > 0\n");
465 ok(clsids != NULL, "Expected clsids != NULL\n");
466 ok(check_clsid(clsids, count), "Filter was not part of enumeration\n");
467 CoTaskMemFree(clsids);
469 /* exchange input and output */
470 count = 0;
471 clsids = NULL;
472 ret = MFTEnum(MFT_CATEGORY_OTHER, 0, output, input, NULL, &clsids, &count);
473 ok(ret == S_OK, "Failed to enumerate filters: %x\n", ret);
474 ok(!count, "got %d\n", count);
475 ok(clsids == NULL, "Expected clsids == NULL\n");
477 ret = MFTUnregister(DUMMY_CLSID);
478 ok(ret == S_OK ||
479 /* w7pro64 */
480 broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
482 ret = MFTUnregister(DUMMY_CLSID);
483 ok(ret == S_OK || broken(ret == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)), "got %x\n", ret);
486 static HRESULT WINAPI test_create_from_url_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
488 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
489 IMFSourceResolver *resolver;
490 IUnknown *object, *object2;
491 MF_OBJECT_TYPE obj_type;
492 HRESULT hr;
494 ok(!!result, "Unexpected result object.\n");
496 resolver = (IMFSourceResolver *)IMFAsyncResult_GetStateNoAddRef(result);
498 object = NULL;
499 hr = IMFSourceResolver_EndCreateObjectFromURL(resolver, result, &obj_type, &object);
500 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
502 hr = IMFAsyncResult_GetObject(result, &object2);
503 ok(hr == S_OK, "Failed to get result object, hr %#x.\n", hr);
504 ok(object2 == object, "Unexpected object.\n");
506 if (object)
507 IUnknown_Release(object);
508 IUnknown_Release(object2);
510 SetEvent(callback->event);
512 return S_OK;
515 static const IMFAsyncCallbackVtbl test_create_from_url_callback_vtbl =
517 testcallback_QueryInterface,
518 testcallback_AddRef,
519 testcallback_Release,
520 testcallback_GetParameters,
521 test_create_from_url_callback_Invoke,
524 static HRESULT WINAPI test_create_from_file_handler_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
526 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
527 IMFSchemeHandler *handler;
528 IUnknown *object, *object2;
529 MF_OBJECT_TYPE obj_type;
530 HRESULT hr;
532 ok(!!result, "Unexpected result object.\n");
534 handler = (IMFSchemeHandler *)IMFAsyncResult_GetStateNoAddRef(result);
536 hr = IMFSchemeHandler_EndCreateObject(handler, result, &obj_type, &object);
537 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
539 if (SUCCEEDED(hr))
541 hr = IMFAsyncResult_GetObject(result, &object2);
542 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
544 IUnknown_Release(object);
547 SetEvent(callback->event);
549 return S_OK;
552 static const IMFAsyncCallbackVtbl test_create_from_file_handler_callback_vtbl =
554 testcallback_QueryInterface,
555 testcallback_AddRef,
556 testcallback_Release,
557 testcallback_GetParameters,
558 test_create_from_file_handler_callback_Invoke,
561 static HRESULT WINAPI source_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
563 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
564 IMFMediaEventGenerator *generator;
565 HRESULT hr;
567 ok(!!result, "Unexpected result object.\n");
569 generator = (IMFMediaEventGenerator *)IMFAsyncResult_GetStateNoAddRef(result);
571 hr = IMFMediaEventGenerator_EndGetEvent(generator, result, &callback->media_event);
572 ok(hr == S_OK, "Failed to create an object, hr %#x.\n", hr);
574 SetEvent(callback->event);
576 return S_OK;
579 static const IMFAsyncCallbackVtbl events_callback_vtbl =
581 testcallback_QueryInterface,
582 testcallback_AddRef,
583 testcallback_Release,
584 testcallback_GetParameters,
585 source_events_callback_Invoke,
588 static BOOL get_event(IMFMediaEventGenerator *generator, MediaEventType expected_event_type, PROPVARIANT *value)
590 struct test_callback callback = {{ 0 }};
591 MediaEventType event_type;
592 BOOL ret = FALSE;
593 HRESULT hr;
595 callback.IMFAsyncCallback_iface.lpVtbl = &events_callback_vtbl;
596 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
598 for (;;)
600 hr = IMFMediaEventGenerator_BeginGetEvent(generator, &callback.IMFAsyncCallback_iface,
601 (IUnknown *)generator);
602 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
604 if (WaitForSingleObject(callback.event, 1000) == WAIT_TIMEOUT)
606 ok(0, "timeout\n");
607 break;
610 Sleep(10);
612 hr = IMFMediaEvent_GetType(callback.media_event, &event_type);
613 ok(hr == S_OK, "Failed to event type, hr %#x.\n", hr);
615 if ((ret = (event_type == expected_event_type)))
617 if (value)
619 hr = IMFMediaEvent_GetValue(callback.media_event, value);
620 ok(hr == S_OK, "Failed to get value of event, hr %#x.\n", hr);
623 break;
627 CloseHandle(callback.event);
628 if (callback.media_event)
629 IMFMediaEvent_Release(callback.media_event);
631 return ret;
634 static void test_source_resolver(void)
636 struct test_callback callback = { { &test_create_from_url_callback_vtbl } };
637 struct test_callback callback2 = { { &test_create_from_file_handler_callback_vtbl } };
638 IMFSourceResolver *resolver, *resolver2;
639 IMFPresentationDescriptor *descriptor;
640 IMFSchemeHandler *scheme_handler;
641 IMFMediaStream *video_stream;
642 IMFAttributes *attributes;
643 IMFMediaSource *mediasource;
644 IMFMediaTypeHandler *handler;
645 IMFMediaType *media_type;
646 BOOL selected, do_uninit;
647 MF_OBJECT_TYPE obj_type;
648 IMFStreamDescriptor *sd;
649 IUnknown *cancel_cookie;
650 IMFByteStream *stream;
651 WCHAR pathW[MAX_PATH];
652 int i, sample_count;
653 WCHAR *filename;
654 PROPVARIANT var;
655 HRESULT hr;
656 GUID guid;
658 if (!pMFCreateSourceResolver)
660 win_skip("MFCreateSourceResolver() not found\n");
661 return;
664 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
665 ok(hr == S_OK, "got 0x%08x\n", hr);
667 hr = pMFCreateSourceResolver(NULL);
668 ok(hr == E_POINTER, "got %#x\n", hr);
670 hr = pMFCreateSourceResolver(&resolver);
671 ok(hr == S_OK, "got %#x\n", hr);
673 hr = pMFCreateSourceResolver(&resolver2);
674 ok(hr == S_OK, "got %#x\n", hr);
675 ok(resolver != resolver2, "Expected new instance\n");
677 IMFSourceResolver_Release(resolver2);
679 filename = load_resource(L"test.mp4");
681 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
682 ok(hr == S_OK, "got 0x%08x\n", hr);
684 hr = IMFSourceResolver_CreateObjectFromByteStream(
685 resolver, NULL, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
686 &obj_type, (IUnknown **)&mediasource);
687 ok(hr == E_POINTER, "got 0x%08x\n", hr);
689 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
690 NULL, (IUnknown **)&mediasource);
691 ok(hr == E_POINTER, "got 0x%08x\n", hr);
693 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
694 &obj_type, NULL);
695 ok(hr == E_POINTER, "got 0x%08x\n", hr);
697 IMFByteStream_Release(stream);
699 /* Create from URL. */
700 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
702 hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"nonexisting.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
703 (IUnknown **)&stream);
704 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "Unexpected hr %#x.\n", hr);
706 hr = IMFSourceResolver_CreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
707 (IUnknown **)&stream);
708 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
709 IMFByteStream_Release(stream);
711 hr = IMFSourceResolver_BeginCreateObjectFromURL(resolver, filename, MF_RESOLUTION_BYTESTREAM, NULL,
712 &cancel_cookie, &callback.IMFAsyncCallback_iface, (IUnknown *)resolver);
713 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
714 ok(cancel_cookie != NULL, "Unexpected cancel object.\n");
715 IUnknown_Release(cancel_cookie);
717 if (SUCCEEDED(hr))
718 WaitForSingleObject(callback.event, INFINITE);
720 /* With explicit scheme. */
721 lstrcpyW(pathW, fileschemeW);
722 lstrcatW(pathW, filename);
724 hr = IMFSourceResolver_CreateObjectFromURL(resolver, pathW, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type,
725 (IUnknown **)&stream);
726 ok(hr == S_OK, "Failed to resolve url, hr %#x.\n", hr);
727 IMFByteStream_Release(stream);
729 /* We have to create a new bytestream here, because all following
730 * calls to CreateObjectFromByteStream will fail. */
731 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
732 ok(hr == S_OK, "got 0x%08x\n", hr);
734 hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes);
735 ok(hr == S_OK, "got 0x%08x\n", hr);
736 hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, L"video/mp4");
737 ok(hr == S_OK, "Failed to set string value, hr %#x.\n", hr);
738 IMFAttributes_Release(attributes);
740 /* Start of gstreamer dependent tests */
742 hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
743 &obj_type, (IUnknown **)&mediasource);
744 if (strcmp(winetest_platform, "wine"))
745 ok(hr == S_OK, "got 0x%08x\n", hr);
746 if (FAILED(hr))
748 IMFByteStream_Release(stream);
749 IMFSourceResolver_Release(resolver);
751 hr = MFShutdown();
752 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
754 DeleteFileW(filename);
755 return;
757 ok(mediasource != NULL, "got %p\n", mediasource);
758 ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type);
760 check_interface(mediasource, &IID_IMFGetService, TRUE);
761 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
762 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
763 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
764 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
765 ok(descriptor != NULL, "got %p\n", descriptor);
767 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
768 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
770 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
771 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
772 IMFStreamDescriptor_Release(sd);
774 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
775 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
777 /* Check major/minor type for the test media. */
778 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
780 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
781 ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
782 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
783 ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
784 todo_wine
785 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
786 IMFMediaType_Release(media_type);
788 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
789 ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr);
791 var.vt = VT_EMPTY;
792 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
793 ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
795 video_stream = NULL;
796 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
798 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
799 video_stream = (IMFMediaStream *)var.punkVal;
802 sample_count = 10;
804 for (i = 0; i < sample_count; ++i)
806 hr = IMFMediaStream_RequestSample(video_stream, NULL);
807 if (i == sample_count)
808 break;
809 ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
810 if (hr != S_OK)
811 break;
814 for (i = 0; i < sample_count; ++i)
816 static const LONGLONG MILLI_TO_100_NANO = 10000;
817 LONGLONG duration, time;
818 DWORD buffer_count;
819 IMFSample *sample;
820 BOOL ret;
822 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
823 ok(ret, "Sample %u not received.\n", i + 1);
824 if (!ret)
825 break;
827 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
828 sample = (IMFSample *)var.punkVal;
830 hr = IMFSample_GetBufferCount(sample, &buffer_count);
831 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
832 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
834 hr = IMFSample_GetSampleDuration(sample, &duration);
835 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
836 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
838 hr = IMFSample_GetSampleTime(sample, &time);
839 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
840 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
842 IMFSample_Release(sample);
845 if (i == sample_count)
847 IMFMediaEvent *event;
849 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
850 Sleep(100);
851 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
852 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
854 hr = IMFMediaStream_RequestSample(video_stream, NULL);
855 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
856 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
860 hr = IMFMediaStream_RequestSample(video_stream, NULL);
861 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
863 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
865 IMFMediaStream_Release(video_stream);
866 IMFMediaTypeHandler_Release(handler);
867 IMFPresentationDescriptor_Release(descriptor);
869 hr = IMFMediaSource_Shutdown(mediasource);
870 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
872 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
873 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
875 IMFMediaSource_Release(mediasource);
876 IMFByteStream_Release(stream);
878 /* Create directly through scheme handler. */
879 hr = CoInitialize(NULL);
880 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
881 do_uninit = hr == S_OK;
883 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
884 (void **)&scheme_handler);
885 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
887 callback2.event = callback.event;
888 cancel_cookie = NULL;
889 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
890 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
891 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
892 ok(!!cancel_cookie, "Unexpected cancel object.\n");
893 IUnknown_Release(cancel_cookie);
895 WaitForSingleObject(callback2.event, INFINITE);
897 IMFSchemeHandler_Release(scheme_handler);
899 if (do_uninit)
900 CoUninitialize();
902 CloseHandle(callback.event);
904 IMFSourceResolver_Release(resolver);
906 hr = MFShutdown();
907 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
909 DeleteFileW(filename);
912 static void init_functions(void)
914 HMODULE mod = GetModuleHandleA("mfplat.dll");
916 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
917 X(MFAddPeriodicCallback);
918 X(MFAllocateSerialWorkQueue);
919 X(MFAllocateWorkQueueEx);
920 X(MFCopyImage);
921 X(MFCreate2DMediaBuffer);
922 X(MFCreateDXGIDeviceManager);
923 X(MFCreateDXGISurfaceBuffer);
924 X(MFCreateDXSurfaceBuffer);
925 X(MFCreateSourceResolver);
926 X(MFCreateMediaBufferFromMediaType);
927 X(MFCreateMFByteStreamOnStream);
928 X(MFCreateTrackedSample);
929 X(MFCreateTransformActivate);
930 X(MFCreateVideoMediaTypeFromSubtype);
931 X(MFCreateVideoSampleAllocatorEx);
932 X(MFGetPlaneSize);
933 X(MFGetStrideForBitmapInfoHeader);
934 X(MFLockSharedWorkQueue);
935 X(MFMapDX9FormatToDXGIFormat);
936 X(MFMapDXGIFormatToDX9Format);
937 X(MFPutWaitingWorkItem);
938 X(MFRegisterLocalByteStreamHandler);
939 X(MFRegisterLocalSchemeHandler);
940 X(MFRemovePeriodicCallback);
941 X(MFTEnumEx);
942 X(MFTRegisterLocal);
943 X(MFTRegisterLocalByCLSID);
944 X(MFTUnregisterLocal);
945 X(MFTUnregisterLocalByCLSID);
947 if ((mod = LoadLibraryA("d3d11.dll")))
949 X(D3D11CreateDevice);
952 mod = GetModuleHandleA("ole32.dll");
954 X(CoGetApartmentType);
955 #undef X
957 is_win8_plus = pMFPutWaitingWorkItem != NULL;
960 static void test_media_type(void)
962 IMFMediaType *mediatype, *mediatype2;
963 IMFVideoMediaType *video_type;
964 IUnknown *unk, *unk2;
965 DWORD count, flags;
966 BOOL compressed;
967 HRESULT hr;
968 GUID guid;
970 if(0)
972 /* Crash on Windows Vista/7 */
973 hr = MFCreateMediaType(NULL);
974 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
977 hr = MFCreateMediaType(&mediatype);
978 ok(hr == S_OK, "got 0x%08x\n", hr);
980 hr = IMFMediaType_GetMajorType(mediatype, &guid);
981 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
983 compressed = FALSE;
984 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
985 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
986 ok(compressed, "Unexpected value %d.\n", compressed);
988 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
989 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
991 compressed = FALSE;
992 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
993 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
994 ok(compressed, "Unexpected value %d.\n", compressed);
996 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 0);
997 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
999 compressed = FALSE;
1000 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1001 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
1002 ok(compressed, "Unexpected value %d.\n", compressed);
1004 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
1005 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1007 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_COMPRESSED, 1);
1008 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1010 compressed = TRUE;
1011 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1012 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
1013 ok(!compressed, "Unexpected value %d.\n", compressed);
1015 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_COMPRESSED);
1016 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1018 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1019 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1021 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1022 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
1023 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1025 /* IsEqual() */
1026 hr = MFCreateMediaType(&mediatype2);
1027 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1029 flags = 0xdeadbeef;
1030 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1031 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1032 ok(flags == 0, "Unexpected flags %#x.\n", flags);
1034 /* Different major types. */
1035 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1036 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
1038 flags = 0;
1039 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1040 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1041 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1042 "Unexpected flags %#x.\n", flags);
1044 /* Same major types, different subtypes. */
1045 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1046 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
1048 flags = 0;
1049 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1050 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1051 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1052 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
1054 /* Different user data. */
1055 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1056 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1058 flags = 0;
1059 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1060 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1061 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1062 "Unexpected flags %#x.\n", flags);
1064 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1065 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1067 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1068 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
1070 flags = 0;
1071 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1072 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1073 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1074 "Unexpected flags %#x.\n", flags);
1076 IMFMediaType_Release(mediatype2);
1077 IMFMediaType_Release(mediatype);
1079 /* IMFVideoMediaType */
1080 hr = MFCreateMediaType(&mediatype);
1081 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1083 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1085 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1086 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1087 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1088 IUnknown_Release(unk);
1090 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1091 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1093 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1094 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1096 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1097 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1098 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1099 IUnknown_Release(unk2);
1101 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1102 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1103 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1104 IUnknown_Release(unk2);
1106 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1107 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1108 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1109 IUnknown_Release(unk2);
1111 IUnknown_Release(unk);
1112 IMFMediaType_Release(mediatype);
1114 if (pMFCreateVideoMediaTypeFromSubtype)
1116 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1117 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1119 check_interface(video_type, &IID_IMFMediaType, TRUE);
1120 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1122 /* Major and subtype are set on creation. */
1123 hr = IMFVideoMediaType_GetCount(video_type, &count);
1124 ok(count == 2, "Unexpected attribute count %#x.\n", hr);
1126 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1127 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1129 hr = IMFVideoMediaType_GetCount(video_type, &count);
1130 ok(!count, "Unexpected attribute count %#x.\n", hr);
1132 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1134 IMFVideoMediaType_Release(video_type);
1136 else
1137 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1139 /* IMFAudioMediaType */
1140 hr = MFCreateMediaType(&mediatype);
1141 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1143 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1145 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1146 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1147 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1148 IUnknown_Release(unk);
1150 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1151 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1153 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1154 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1156 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1157 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1158 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1159 IUnknown_Release(unk2);
1161 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1162 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1163 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1164 IUnknown_Release(unk2);
1166 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1167 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1168 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1169 IUnknown_Release(unk2);
1171 IUnknown_Release(unk);
1173 IMFMediaType_Release(mediatype);
1176 static void test_MFCreateMediaEvent(void)
1178 HRESULT hr;
1179 IMFMediaEvent *mediaevent;
1181 MediaEventType type;
1182 GUID extended_type;
1183 HRESULT status;
1184 PROPVARIANT value;
1186 PropVariantInit(&value);
1187 value.vt = VT_UNKNOWN;
1189 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1190 ok(hr == S_OK, "got 0x%08x\n", hr);
1192 PropVariantClear(&value);
1194 hr = IMFMediaEvent_GetType(mediaevent, &type);
1195 ok(hr == S_OK, "got 0x%08x\n", hr);
1196 ok(type == MEError, "got %#x\n", type);
1198 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1199 ok(hr == S_OK, "got 0x%08x\n", hr);
1200 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1201 wine_dbgstr_guid(&extended_type));
1203 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1204 ok(hr == S_OK, "got 0x%08x\n", hr);
1205 ok(status == E_FAIL, "got 0x%08x\n", status);
1207 PropVariantInit(&value);
1208 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1209 ok(hr == S_OK, "got 0x%08x\n", hr);
1210 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1211 PropVariantClear(&value);
1213 IMFMediaEvent_Release(mediaevent);
1215 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1216 ok(hr == S_OK, "got 0x%08x\n", hr);
1218 hr = IMFMediaEvent_GetType(mediaevent, &type);
1219 ok(hr == S_OK, "got 0x%08x\n", hr);
1220 ok(type == MEUnknown, "got %#x\n", type);
1222 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1223 ok(hr == S_OK, "got 0x%08x\n", hr);
1224 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1225 wine_dbgstr_guid(&extended_type));
1227 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1228 ok(hr == S_OK, "got 0x%08x\n", hr);
1229 ok(status == S_OK, "got 0x%08x\n", status);
1231 PropVariantInit(&value);
1232 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1233 ok(hr == S_OK, "got 0x%08x\n", hr);
1234 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1235 PropVariantClear(&value);
1237 IMFMediaEvent_Release(mediaevent);
1240 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1241 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1243 UINT32 count = expected + 1;
1244 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1245 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1246 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1249 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1250 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1252 MF_ATTRIBUTE_TYPE type;
1253 HRESULT hr;
1255 hr = IMFAttributes_GetItemType(obj, key, &type);
1256 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1257 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1260 static void test_attributes(void)
1262 static const WCHAR stringW[] = L"Wine";
1263 static const UINT8 blob[] = {0,1,2,3,4,5};
1264 IMFAttributes *attributes, *attributes1;
1265 UINT8 blob_value[256], *blob_buf = NULL;
1266 MF_ATTRIBUTES_MATCH_TYPE match_type;
1267 UINT32 value, string_length, size;
1268 PROPVARIANT propvar, ret_propvar;
1269 MF_ATTRIBUTE_TYPE type;
1270 double double_value;
1271 IUnknown *unk_value;
1272 WCHAR bufferW[256];
1273 UINT64 value64;
1274 WCHAR *string;
1275 BOOL result;
1276 HRESULT hr;
1277 GUID key;
1279 hr = MFCreateAttributes( &attributes, 3 );
1280 ok(hr == S_OK, "got 0x%08x\n", hr);
1282 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1283 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1285 CHECK_ATTR_COUNT(attributes, 0);
1286 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1287 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
1288 CHECK_ATTR_COUNT(attributes, 1);
1289 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1291 value = 0xdeadbeef;
1292 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1293 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
1294 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1296 value64 = 0xdeadbeef;
1297 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1298 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1299 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1301 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1302 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
1303 CHECK_ATTR_COUNT(attributes, 1);
1304 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1306 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1307 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
1308 ok(value64 == 65536, "Unexpected value.\n");
1310 value = 0xdeadbeef;
1311 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1312 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1313 ok(value == 0xdeadbeef, "Unexpected value.\n");
1315 IMFAttributes_Release(attributes);
1317 hr = MFCreateAttributes(&attributes, 0);
1318 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1320 PropVariantInit(&propvar);
1321 propvar.vt = MF_ATTRIBUTE_UINT32;
1322 U(propvar).ulVal = 123;
1323 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1324 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1325 PropVariantInit(&ret_propvar);
1326 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1327 U(ret_propvar).ulVal = 0xdeadbeef;
1328 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1329 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1330 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1331 PropVariantClear(&ret_propvar);
1332 CHECK_ATTR_COUNT(attributes, 1);
1334 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1335 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
1337 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1338 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1340 PropVariantInit(&ret_propvar);
1341 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1342 U(ret_propvar).pwszVal = NULL;
1343 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1344 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1345 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1346 PropVariantClear(&ret_propvar);
1348 PropVariantClear(&propvar);
1350 PropVariantInit(&propvar);
1351 propvar.vt = MF_ATTRIBUTE_UINT64;
1352 U(propvar).uhVal.QuadPart = 65536;
1353 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1354 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1355 PropVariantInit(&ret_propvar);
1356 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1357 U(ret_propvar).ulVal = 0xdeadbeef;
1358 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1359 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1360 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1361 PropVariantClear(&ret_propvar);
1362 PropVariantClear(&propvar);
1363 CHECK_ATTR_COUNT(attributes, 1);
1365 PropVariantInit(&propvar);
1366 propvar.vt = VT_I4;
1367 U(propvar).lVal = 123;
1368 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1369 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
1370 PropVariantInit(&ret_propvar);
1371 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1372 U(ret_propvar).lVal = 0xdeadbeef;
1373 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1374 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1375 PropVariantClear(&propvar);
1376 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1377 PropVariantClear(&ret_propvar);
1379 PropVariantInit(&propvar);
1380 propvar.vt = MF_ATTRIBUTE_UINT32;
1381 U(propvar).ulVal = 123;
1382 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1383 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1385 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1386 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1387 CHECK_ATTR_COUNT(attributes, 2);
1389 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1390 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1391 CHECK_ATTR_COUNT(attributes, 2);
1393 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1394 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1395 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1396 PropVariantClear(&ret_propvar);
1397 PropVariantClear(&propvar);
1399 propvar.vt = MF_ATTRIBUTE_UINT64;
1400 U(propvar).uhVal.QuadPart = 65536;
1402 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1403 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1404 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1405 PropVariantClear(&ret_propvar);
1406 PropVariantClear(&propvar);
1408 /* Item ordering is not consistent across Windows version. */
1409 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1410 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1411 PropVariantClear(&ret_propvar);
1413 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1414 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1415 PropVariantClear(&ret_propvar);
1417 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1418 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
1419 CHECK_ATTR_COUNT(attributes, 3);
1420 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1422 double_value = 0xdeadbeef;
1423 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1424 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
1425 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1427 propvar.vt = MF_ATTRIBUTE_UINT64;
1428 U(propvar).uhVal.QuadPart = 22;
1429 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1430 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1431 ok(!result, "Unexpected result.\n");
1433 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1434 U(propvar).dblVal = 22.0;
1435 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1436 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1437 ok(result, "Unexpected result.\n");
1439 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1440 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
1441 CHECK_ATTR_COUNT(attributes, 3);
1442 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1444 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1445 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
1446 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1448 string_length = 0xdeadbeef;
1449 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1450 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
1451 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1452 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1453 CoTaskMemFree(string);
1455 string_length = 0xdeadbeef;
1456 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1457 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1458 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1459 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1460 memset(bufferW, 0, sizeof(bufferW));
1462 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1463 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1464 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1465 memset(bufferW, 0, sizeof(bufferW));
1467 string_length = 0;
1468 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1469 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1470 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1471 ok(string_length, "Unexpected length.\n");
1473 string_length = 0xdeadbeef;
1474 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1475 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1476 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1478 /* VT_UNKNOWN */
1479 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1480 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1481 CHECK_ATTR_COUNT(attributes, 4);
1482 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1484 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1485 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1486 IUnknown_Release(unk_value);
1488 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1489 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1490 IUnknown_Release(unk_value);
1492 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1493 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1495 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1496 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1497 CHECK_ATTR_COUNT(attributes, 5);
1499 unk_value = NULL;
1500 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1501 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1503 /* CopyAllItems() */
1504 hr = MFCreateAttributes(&attributes1, 0);
1505 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1506 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1507 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1508 CHECK_ATTR_COUNT(attributes, 5);
1509 CHECK_ATTR_COUNT(attributes1, 5);
1511 hr = IMFAttributes_DeleteAllItems(attributes1);
1512 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
1513 CHECK_ATTR_COUNT(attributes1, 0);
1515 propvar.vt = MF_ATTRIBUTE_UINT64;
1516 U(propvar).uhVal.QuadPart = 22;
1517 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1518 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1519 ok(!result, "Unexpected result.\n");
1521 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1522 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1523 CHECK_ATTR_COUNT(attributes, 0);
1525 /* Blob */
1526 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1527 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
1528 CHECK_ATTR_COUNT(attributes, 1);
1529 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1530 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1531 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1532 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1534 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1535 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1537 size = 0;
1538 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1539 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1540 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1541 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1543 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1544 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1546 memset(blob_value, 0, sizeof(blob_value));
1547 size = 0;
1548 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1549 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1550 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1551 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1552 CoTaskMemFree(blob_buf);
1554 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1555 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1557 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1558 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1560 IMFAttributes_Release(attributes);
1561 IMFAttributes_Release(attributes1);
1563 /* Compare() */
1564 hr = MFCreateAttributes(&attributes, 0);
1565 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1566 hr = MFCreateAttributes(&attributes1, 0);
1567 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1569 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1570 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1572 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1574 result = FALSE;
1575 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1576 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1577 ok(result, "Unexpected result %d.\n", result);
1579 result = FALSE;
1580 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1581 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1582 ok(result, "Unexpected result %d.\n", result);
1585 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1586 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1588 result = TRUE;
1589 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1590 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1591 ok(!result, "Unexpected result %d.\n", result);
1593 result = TRUE;
1594 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1595 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1596 ok(!result, "Unexpected result %d.\n", result);
1598 result = FALSE;
1599 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1600 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1601 ok(result, "Unexpected result %d.\n", result);
1603 result = FALSE;
1604 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1605 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1606 ok(result, "Unexpected result %d.\n", result);
1608 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1609 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1611 result = TRUE;
1612 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1613 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1614 ok(!result, "Unexpected result %d.\n", result);
1616 result = TRUE;
1617 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1618 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1619 ok(!result, "Unexpected result %d.\n", result);
1621 result = TRUE;
1622 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1623 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1624 ok(!result, "Unexpected result %d.\n", result);
1626 result = TRUE;
1627 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1628 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1629 ok(!result, "Unexpected result %d.\n", result);
1631 result = TRUE;
1632 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1633 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1634 ok(!result, "Unexpected result %d.\n", result);
1636 result = TRUE;
1637 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1638 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1639 ok(!result, "Unexpected result %d.\n", result);
1641 result = TRUE;
1642 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1643 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1644 ok(!result, "Unexpected result %d.\n", result);
1646 result = TRUE;
1647 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1648 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1649 ok(!result, "Unexpected result %d.\n", result);
1651 result = TRUE;
1652 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1653 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1654 ok(!result, "Unexpected result %d.\n", result);
1656 result = TRUE;
1657 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1658 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1659 ok(!result, "Unexpected result %d.\n", result);
1661 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1662 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1664 result = FALSE;
1665 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1666 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1667 ok(result, "Unexpected result %d.\n", result);
1669 result = FALSE;
1670 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1671 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1672 ok(result, "Unexpected result %d.\n", result);
1674 result = FALSE;
1675 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1676 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1677 ok(result, "Unexpected result %d.\n", result);
1679 result = FALSE;
1680 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1681 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1682 ok(result, "Unexpected result %d.\n", result);
1684 result = FALSE;
1685 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1686 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1687 ok(result, "Unexpected result %d.\n", result);
1689 result = FALSE;
1690 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1691 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1692 ok(result, "Unexpected result %d.\n", result);
1694 result = FALSE;
1695 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1696 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1697 ok(result, "Unexpected result %d.\n", result);
1699 result = FALSE;
1700 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1701 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1702 ok(result, "Unexpected result %d.\n", result);
1704 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1705 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1707 result = TRUE;
1708 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1709 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1710 ok(!result, "Unexpected result %d.\n", result);
1712 result = TRUE;
1713 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1714 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1715 ok(!result, "Unexpected result %d.\n", result);
1717 result = FALSE;
1718 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1719 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1720 ok(result, "Unexpected result %d.\n", result);
1722 result = FALSE;
1723 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1724 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1725 ok(result, "Unexpected result %d.\n", result);
1727 result = FALSE;
1728 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1729 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1730 ok(result, "Unexpected result %d.\n", result);
1732 result = TRUE;
1733 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1734 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1735 ok(!result, "Unexpected result %d.\n", result);
1737 result = FALSE;
1738 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1739 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1740 ok(result, "Unexpected result %d.\n", result);
1742 result = TRUE;
1743 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1744 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1745 ok(!result, "Unexpected result %d.\n", result);
1747 result = FALSE;
1748 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1749 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1750 ok(result, "Unexpected result %d.\n", result);
1752 result = FALSE;
1753 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1754 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1755 ok(result, "Unexpected result %d.\n", result);
1757 IMFAttributes_Release(attributes);
1758 IMFAttributes_Release(attributes1);
1761 static void test_MFCreateMFByteStreamOnStream(void)
1763 IMFByteStream *bytestream;
1764 IMFByteStream *bytestream2;
1765 IStream *stream;
1766 IMFAttributes *attributes = NULL;
1767 DWORD caps, written, count;
1768 IUnknown *unknown;
1769 ULONG ref, size;
1770 HRESULT hr;
1772 if(!pMFCreateMFByteStreamOnStream)
1774 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1775 return;
1778 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1779 ok(hr == S_OK, "got 0x%08x\n", hr);
1781 caps = 0xffff0000;
1782 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1783 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1785 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1786 ok(hr == S_OK, "got 0x%08x\n", hr);
1788 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1789 (void **)&unknown);
1790 ok(hr == S_OK, "got 0x%08x\n", hr);
1791 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1792 ref = IUnknown_Release(unknown);
1793 ok(ref == 1, "got %u\n", ref);
1795 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1796 (void **)&bytestream2);
1797 ok(hr == S_OK, "got 0x%08x\n", hr);
1798 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1799 ref = IMFByteStream_Release(bytestream2);
1800 ok(ref == 1, "got %u\n", ref);
1802 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1803 (void **)&attributes);
1804 ok(hr == S_OK ||
1805 /* w7pro64 */
1806 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1808 if (hr != S_OK)
1810 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1811 IStream_Release(stream);
1812 IMFByteStream_Release(bytestream);
1813 return;
1816 ok(attributes != NULL, "got NULL\n");
1817 hr = IMFAttributes_GetCount(attributes, &count);
1818 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1819 ok(count == 0, "Unexpected attributes count %u.\n", count);
1821 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1822 (void **)&unknown);
1823 ok(hr == S_OK, "got 0x%08x\n", hr);
1824 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1825 ref = IUnknown_Release(unknown);
1826 ok(ref == 2, "got %u\n", ref);
1828 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1829 (void **)&bytestream2);
1830 ok(hr == S_OK, "got 0x%08x\n", hr);
1831 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1832 ref = IMFByteStream_Release(bytestream2);
1833 ok(ref == 2, "got %u\n", ref);
1835 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1836 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1837 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1838 check_interface(bytestream, &IID_IMFGetService, FALSE);
1840 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1841 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1842 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1844 hr = IMFByteStream_Close(bytestream);
1845 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1847 hr = IMFByteStream_Close(bytestream);
1848 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1850 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1851 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1852 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1854 caps = 0;
1855 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1856 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1857 ok(caps == 0xffff0000, "Unexpected content.\n");
1859 IMFAttributes_Release(attributes);
1860 IMFByteStream_Release(bytestream);
1861 IStream_Release(stream);
1864 static void test_file_stream(void)
1866 static const WCHAR newfilename[] = L"new.mp4";
1867 IMFByteStream *bytestream, *bytestream2;
1868 QWORD bytestream_length, position;
1869 IMFAttributes *attributes = NULL;
1870 MF_ATTRIBUTE_TYPE item_type;
1871 WCHAR pathW[MAX_PATH];
1872 DWORD caps, count;
1873 WCHAR *filename;
1874 HRESULT hr;
1875 WCHAR *str;
1876 BOOL eos;
1878 filename = load_resource(L"test.mp4");
1880 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1881 ok(hr == S_OK, "got 0x%08x\n", hr);
1883 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1884 MF_FILEFLAGS_NONE, filename, &bytestream);
1885 ok(hr == S_OK, "got 0x%08x\n", hr);
1887 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1888 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1889 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1890 check_interface(bytestream, &IID_IMFGetService, TRUE);
1892 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1893 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1894 if (is_win8_plus)
1896 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1897 "Unexpected caps %#x.\n", caps);
1899 else
1900 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1902 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1903 (void **)&attributes);
1904 ok(hr == S_OK, "got 0x%08x\n", hr);
1905 ok(attributes != NULL, "got NULL\n");
1907 hr = IMFAttributes_GetCount(attributes, &count);
1908 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1909 ok(count == 2, "Unexpected attributes count %u.\n", count);
1911 /* Original file name. */
1912 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1913 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1914 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1915 CoTaskMemFree(str);
1917 /* Modification time. */
1918 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1919 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1920 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1922 IMFAttributes_Release(attributes);
1924 /* Length. */
1925 hr = IMFByteStream_GetLength(bytestream, NULL);
1926 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1928 bytestream_length = 0;
1929 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1930 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1931 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1933 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1934 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1936 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1937 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1938 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1940 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1941 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1943 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1944 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1946 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1947 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1948 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1950 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1951 MF_FILEFLAGS_NONE, filename, &bytestream2);
1952 ok(hr == S_OK, "got 0x%08x\n", hr);
1953 IMFByteStream_Release(bytestream2);
1955 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1956 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1958 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1959 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1961 IMFByteStream_Release(bytestream);
1963 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1964 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1965 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1967 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1968 MF_FILEFLAGS_NONE, filename, &bytestream);
1969 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1971 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1972 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1973 ok(hr == S_OK, "got 0x%08x\n", hr);
1975 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1976 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1978 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1979 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1981 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1982 newfilename, &bytestream2);
1983 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1985 IMFByteStream_Release(bytestream);
1987 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1988 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1989 ok(hr == S_OK, "got 0x%08x\n", hr);
1991 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1992 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1993 newfilename, &bytestream2);
1994 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1996 IMFByteStream_Release(bytestream);
1998 /* Explicit file: scheme */
1999 lstrcpyW(pathW, fileschemeW);
2000 lstrcatW(pathW, filename);
2001 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
2002 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2004 hr = MFShutdown();
2005 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2007 DeleteFileW(filename);
2008 DeleteFileW(newfilename);
2011 static void test_system_memory_buffer(void)
2013 IMFMediaBuffer *buffer;
2014 HRESULT hr;
2015 DWORD length, max;
2016 BYTE *data, *data2;
2018 hr = MFCreateMemoryBuffer(1024, NULL);
2019 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2021 hr = MFCreateMemoryBuffer(0, &buffer);
2022 ok(hr == S_OK, "got 0x%08x\n", hr);
2023 if(buffer)
2025 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2026 ok(hr == S_OK, "got 0x%08x\n", hr);
2027 ok(length == 0, "got %u\n", length);
2029 IMFMediaBuffer_Release(buffer);
2032 hr = MFCreateMemoryBuffer(1024, &buffer);
2033 ok(hr == S_OK, "got 0x%08x\n", hr);
2035 check_interface(buffer, &IID_IMFGetService, FALSE);
2037 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2038 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2040 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2041 ok(hr == S_OK, "got 0x%08x\n", hr);
2042 ok(length == 1024, "got %u\n", length);
2044 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2045 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2047 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2048 ok(hr == S_OK, "got 0x%08x\n", hr);
2050 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2051 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2053 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2054 ok(hr == S_OK, "got 0x%08x\n", hr);
2055 ok(length == 10, "got %u\n", length);
2057 length = 0;
2058 max = 0;
2059 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2060 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2061 ok(length == 0, "got %u\n", length);
2062 ok(max == 0, "got %u\n", length);
2064 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2065 ok(hr == S_OK, "got 0x%08x\n", hr);
2066 ok(length == 10, "got %u\n", length);
2067 ok(max == 1024, "got %u\n", max);
2069 /* Attempt to lock the buffer twice */
2070 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2071 ok(hr == S_OK, "got 0x%08x\n", hr);
2072 ok(data == data2, "got 0x%08x\n", hr);
2074 hr = IMFMediaBuffer_Unlock(buffer);
2075 ok(hr == S_OK, "got 0x%08x\n", hr);
2077 hr = IMFMediaBuffer_Unlock(buffer);
2078 ok(hr == S_OK, "got 0x%08x\n", hr);
2080 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2081 ok(hr == S_OK, "got 0x%08x\n", hr);
2083 hr = IMFMediaBuffer_Unlock(buffer);
2084 ok(hr == S_OK, "got 0x%08x\n", hr);
2086 /* Extra Unlock */
2087 hr = IMFMediaBuffer_Unlock(buffer);
2088 ok(hr == S_OK, "got 0x%08x\n", hr);
2090 IMFMediaBuffer_Release(buffer);
2092 /* Aligned buffer. */
2093 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2094 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2096 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2097 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
2099 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2100 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2101 ok(length == 0, "Unexpected current length %u.\n", length);
2103 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2104 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2105 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2106 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2107 ok(length == 1, "Unexpected current length %u.\n", length);
2109 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2110 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2111 ok(length == 201, "Unexpected max length %u.\n", length);
2113 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2114 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2115 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2116 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2117 ok(length == 201, "Unexpected max length %u.\n", length);
2118 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2119 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2121 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2122 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
2123 ok(max == 201 && length == 10, "Unexpected length.\n");
2124 hr = IMFMediaBuffer_Unlock(buffer);
2125 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2127 IMFMediaBuffer_Release(buffer);
2130 static void test_sample(void)
2132 static const DWORD test_pattern = 0x22222222;
2133 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2134 DWORD count, flags, length;
2135 IMFAttributes *attributes;
2136 IMFSample *sample;
2137 LONGLONG time;
2138 HRESULT hr;
2139 BYTE *data;
2141 hr = MFCreateSample( &sample );
2142 ok(hr == S_OK, "got 0x%08x\n", hr);
2144 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2145 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
2147 CHECK_ATTR_COUNT(attributes, 0);
2149 hr = IMFSample_GetBufferCount(sample, NULL);
2150 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2152 hr = IMFSample_GetBufferCount(sample, &count);
2153 ok(hr == S_OK, "got 0x%08x\n", hr);
2154 ok(count == 0, "got %d\n", count);
2156 hr = IMFSample_GetSampleFlags(sample, &flags);
2157 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2158 ok(!flags, "Unexpected flags %#x.\n", flags);
2160 hr = IMFSample_SetSampleFlags(sample, 0x123);
2161 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
2162 hr = IMFSample_GetSampleFlags(sample, &flags);
2163 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2164 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2166 hr = IMFSample_GetSampleTime(sample, &time);
2167 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2169 hr = IMFSample_GetSampleDuration(sample, &time);
2170 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2172 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2173 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2175 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2176 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2178 hr = IMFSample_RemoveAllBuffers(sample);
2179 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
2181 hr = IMFSample_GetTotalLength(sample, &length);
2182 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2183 ok(!length, "Unexpected total length %u.\n", length);
2185 hr = MFCreateMemoryBuffer(16, &buffer);
2186 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
2188 hr = IMFSample_AddBuffer(sample, buffer);
2189 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2191 hr = IMFSample_AddBuffer(sample, buffer);
2192 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2194 hr = IMFSample_GetBufferCount(sample, &count);
2195 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2196 ok(count == 2, "Unexpected buffer count %u.\n", count);
2198 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2199 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
2200 ok(buffer2 == buffer, "Unexpected object.\n");
2201 IMFMediaBuffer_Release(buffer2);
2203 hr = IMFSample_GetTotalLength(sample, &length);
2204 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2205 ok(!length, "Unexpected total length %u.\n", length);
2207 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2208 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2210 hr = IMFSample_GetTotalLength(sample, &length);
2211 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2212 ok(length == 4, "Unexpected total length %u.\n", length);
2214 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2215 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
2217 hr = IMFSample_GetTotalLength(sample, &length);
2218 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2219 ok(length == 2, "Unexpected total length %u.\n", length);
2221 IMFMediaBuffer_Release(buffer);
2223 /* Duration */
2224 hr = IMFSample_SetSampleDuration(sample, 10);
2225 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
2226 CHECK_ATTR_COUNT(attributes, 0);
2227 hr = IMFSample_GetSampleDuration(sample, &time);
2228 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
2229 ok(time == 10, "Unexpected duration.\n");
2231 /* Timestamp */
2232 hr = IMFSample_SetSampleTime(sample, 1);
2233 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
2234 CHECK_ATTR_COUNT(attributes, 0);
2235 hr = IMFSample_GetSampleTime(sample, &time);
2236 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
2237 ok(time == 1, "Unexpected timestamp.\n");
2239 IMFAttributes_Release(attributes);
2240 IMFSample_Release(sample);
2242 /* CopyToBuffer() */
2243 hr = MFCreateSample(&sample);
2244 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2246 hr = MFCreateMemoryBuffer(16, &buffer2);
2247 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2249 /* Sample with no buffers. */
2250 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2251 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2252 hr = IMFSample_CopyToBuffer(sample, buffer2);
2253 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2254 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2255 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2256 ok(!length, "Unexpected length %u.\n", length);
2258 /* Single buffer, larger destination. */
2259 hr = MFCreateMemoryBuffer(8, &buffer);
2260 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2262 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2263 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2264 *(DWORD *)data = 0x11111111;
2265 hr = IMFMediaBuffer_Unlock(buffer);
2266 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2267 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2268 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2270 hr = IMFSample_AddBuffer(sample, buffer);
2271 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2273 /* Existing content is overwritten. */
2274 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2275 ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
2277 hr = IMFSample_CopyToBuffer(sample, buffer2);
2278 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2280 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2281 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2282 ok(length == 4, "Unexpected buffer length %u.\n", length);
2284 /* Multiple buffers, matching total size. */
2285 hr = IMFSample_AddBuffer(sample, buffer);
2286 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2288 hr = IMFSample_GetBufferCount(sample, &count);
2289 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2290 ok(count == 2, "Unexpected buffer count %u.\n", count);
2292 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2293 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2295 hr = IMFSample_CopyToBuffer(sample, buffer2);
2296 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2298 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2299 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2300 ok(length == 16, "Unexpected buffer length %u.\n", length);
2302 hr = IMFSample_AddBuffer(sample, buffer);
2303 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2305 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2306 ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
2308 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2309 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2310 *(DWORD *)data = test_pattern;
2311 hr = IMFMediaBuffer_Unlock(buffer2);
2312 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2314 hr = IMFSample_CopyToBuffer(sample, buffer2);
2315 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
2317 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2318 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2319 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
2320 hr = IMFMediaBuffer_Unlock(buffer2);
2321 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2323 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2324 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2325 ok(!length, "Unexpected buffer length %u.\n", length);
2327 IMFMediaBuffer_Release(buffer2);
2328 IMFSample_Release(sample);
2330 /* ConvertToContiguousBuffer() */
2331 hr = MFCreateSample(&sample);
2332 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2334 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2335 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2337 hr = MFCreateMemoryBuffer(16, &buffer);
2338 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2340 hr = IMFSample_AddBuffer(sample, buffer);
2341 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2343 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2344 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2345 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2346 IMFMediaBuffer_Release(buffer2);
2348 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2349 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2351 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2352 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2353 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2354 IMFMediaBuffer_Release(buffer2);
2356 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2357 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2359 hr = MFCreateMemoryBuffer(16, &buffer2);
2360 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2362 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2363 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2365 hr = IMFSample_AddBuffer(sample, buffer2);
2366 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2367 IMFMediaBuffer_Release(buffer2);
2369 hr = IMFSample_GetBufferCount(sample, &count);
2370 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2371 ok(count == 2, "Unexpected buffer count %u.\n", count);
2373 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2374 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2376 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2377 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2378 ok(length == 7, "Unexpected length %u.\n", length);
2380 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2381 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2382 ok(length == 7, "Unexpected length %u.\n", length);
2384 IMFMediaBuffer_Release(buffer3);
2386 hr = IMFSample_GetBufferCount(sample, &count);
2387 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2388 ok(count == 1, "Unexpected buffer count %u.\n", count);
2390 hr = IMFSample_AddBuffer(sample, buffer);
2391 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2393 hr = IMFSample_GetBufferCount(sample, &count);
2394 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2395 ok(count == 2, "Unexpected buffer count %u.\n", count);
2397 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2398 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2400 hr = IMFSample_GetBufferCount(sample, &count);
2401 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2402 ok(count == 1, "Unexpected buffer count %u.\n", count);
2404 IMFMediaBuffer_Release(buffer);
2406 IMFSample_Release(sample);
2409 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2411 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2412 IMFMediaEventQueue *queue;
2413 IUnknown *state, *obj;
2414 HRESULT hr;
2416 ok(result != NULL, "Unexpected result object.\n");
2418 state = IMFAsyncResult_GetStateNoAddRef(result);
2419 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2421 IMFMediaEvent *event = NULL, *event2;
2423 if (is_win8_plus)
2425 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2426 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2428 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2429 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2431 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2432 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
2434 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2435 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
2437 if (event)
2438 IMFMediaEvent_Release(event);
2441 hr = IMFAsyncResult_GetObject(result, &obj);
2442 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2444 IMFMediaEventQueue_Release(queue);
2446 SetEvent(callback->event);
2449 return E_NOTIMPL;
2452 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2454 testcallback_QueryInterface,
2455 testcallback_AddRef,
2456 testcallback_Release,
2457 testcallback_GetParameters,
2458 testcallback_Invoke,
2461 static void init_test_callback(struct test_callback *callback)
2463 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
2464 callback->event = NULL;
2467 static void test_MFCreateAsyncResult(void)
2469 IMFAsyncResult *result, *result2;
2470 struct test_callback callback;
2471 IUnknown *state, *object;
2472 MFASYNCRESULT *data;
2473 ULONG refcount;
2474 HANDLE event;
2475 DWORD flags;
2476 HRESULT hr;
2477 BOOL ret;
2479 init_test_callback(&callback);
2481 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2482 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2484 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2485 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2487 data = (MFASYNCRESULT *)result;
2488 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2489 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2490 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2491 ok(data->hEvent == NULL, "Unexpected event.\n");
2493 hr = IMFAsyncResult_GetState(result, NULL);
2494 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2496 state = (void *)0xdeadbeef;
2497 hr = IMFAsyncResult_GetState(result, &state);
2498 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2499 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2501 hr = IMFAsyncResult_GetStatus(result);
2502 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
2504 data->hrStatusResult = 123;
2505 hr = IMFAsyncResult_GetStatus(result);
2506 ok(hr == 123, "Unexpected status %#x.\n", hr);
2508 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2509 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
2510 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
2512 hr = IMFAsyncResult_GetObject(result, NULL);
2513 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2515 object = (void *)0xdeadbeef;
2516 hr = IMFAsyncResult_GetObject(result, &object);
2517 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
2518 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2520 state = IMFAsyncResult_GetStateNoAddRef(result);
2521 ok(state == NULL, "Unexpected state.\n");
2523 /* Object. */
2524 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
2525 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2527 data = (MFASYNCRESULT *)result2;
2528 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2529 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2530 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2531 ok(data->hEvent == NULL, "Unexpected event.\n");
2533 object = NULL;
2534 hr = IMFAsyncResult_GetObject(result2, &object);
2535 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
2536 ok(object == (IUnknown *)result, "Unexpected object.\n");
2537 IUnknown_Release(object);
2539 IMFAsyncResult_Release(result2);
2541 /* State object. */
2542 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2543 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2545 data = (MFASYNCRESULT *)result2;
2546 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2547 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2548 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2549 ok(data->hEvent == NULL, "Unexpected event.\n");
2551 state = NULL;
2552 hr = IMFAsyncResult_GetState(result2, &state);
2553 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
2554 ok(state == (IUnknown *)result, "Unexpected state.\n");
2555 IUnknown_Release(state);
2557 state = IMFAsyncResult_GetStateNoAddRef(result2);
2558 ok(state == (IUnknown *)result, "Unexpected state.\n");
2560 refcount = IMFAsyncResult_Release(result2);
2561 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2562 refcount = IMFAsyncResult_Release(result);
2563 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2565 /* Event handle is closed on release. */
2566 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2567 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2569 data = (MFASYNCRESULT *)result;
2570 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2571 ok(data->hEvent != NULL, "Failed to create event.\n");
2572 ret = GetHandleInformation(event, &flags);
2573 ok(ret, "Failed to get handle info.\n");
2575 refcount = IMFAsyncResult_Release(result);
2576 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2577 ret = GetHandleInformation(event, &flags);
2578 ok(!ret, "Expected handle to be closed.\n");
2580 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2581 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2583 data = (MFASYNCRESULT *)result;
2584 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2585 ok(data->hEvent != NULL, "Failed to create event.\n");
2586 ret = GetHandleInformation(event, &flags);
2587 ok(ret, "Failed to get handle info.\n");
2589 refcount = IMFAsyncResult_Release(result);
2590 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2591 ret = GetHandleInformation(event, &flags);
2592 ok(!ret, "Expected handle to be closed.\n");
2595 static void test_startup(void)
2597 DWORD queue;
2598 HRESULT hr;
2600 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2601 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
2603 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2604 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2606 hr = MFAllocateWorkQueue(&queue);
2607 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2608 hr = MFUnlockWorkQueue(queue);
2609 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2611 hr = MFShutdown();
2612 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2614 hr = MFAllocateWorkQueue(&queue);
2615 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2617 /* Already shut down, has no effect. */
2618 hr = MFShutdown();
2619 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2621 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2622 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2624 hr = MFAllocateWorkQueue(&queue);
2625 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2626 hr = MFUnlockWorkQueue(queue);
2627 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2629 hr = MFShutdown();
2630 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2632 /* Platform lock. */
2633 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2634 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2636 hr = MFAllocateWorkQueue(&queue);
2637 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2638 hr = MFUnlockWorkQueue(queue);
2639 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2641 /* Unlocking implies shutdown. */
2642 hr = MFUnlockPlatform();
2643 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2645 hr = MFAllocateWorkQueue(&queue);
2646 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2648 hr = MFLockPlatform();
2649 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2651 hr = MFAllocateWorkQueue(&queue);
2652 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2653 hr = MFUnlockWorkQueue(queue);
2654 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2656 hr = MFShutdown();
2657 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2660 static void test_allocate_queue(void)
2662 DWORD queue, queue2;
2663 HRESULT hr;
2665 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2666 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2668 hr = MFAllocateWorkQueue(&queue);
2669 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2670 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2672 hr = MFUnlockWorkQueue(queue);
2673 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2675 hr = MFUnlockWorkQueue(queue);
2676 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2678 hr = MFAllocateWorkQueue(&queue2);
2679 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2680 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2682 hr = MFUnlockWorkQueue(queue2);
2683 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2685 /* Unlock in system queue range. */
2686 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2687 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2689 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2690 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2692 hr = MFUnlockWorkQueue(0x20);
2693 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2695 hr = MFShutdown();
2696 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2699 static void test_MFCopyImage(void)
2701 BYTE dest[16], src[16];
2702 HRESULT hr;
2704 if (!pMFCopyImage)
2706 win_skip("MFCopyImage() is not available.\n");
2707 return;
2710 memset(dest, 0xaa, sizeof(dest));
2711 memset(src, 0x11, sizeof(src));
2713 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2714 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2715 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2717 memset(dest, 0xaa, sizeof(dest));
2718 memset(src, 0x11, sizeof(src));
2720 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2721 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2722 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2724 memset(dest, 0xaa, sizeof(dest));
2725 memset(src, 0x11, sizeof(src));
2727 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2728 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2729 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2732 static void test_MFCreateCollection(void)
2734 IMFCollection *collection;
2735 IUnknown *element;
2736 DWORD count;
2737 HRESULT hr;
2739 hr = MFCreateCollection(NULL);
2740 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2742 hr = MFCreateCollection(&collection);
2743 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2745 hr = IMFCollection_GetElementCount(collection, NULL);
2746 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2748 count = 1;
2749 hr = IMFCollection_GetElementCount(collection, &count);
2750 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2751 ok(count == 0, "Unexpected count %u.\n", count);
2753 hr = IMFCollection_GetElement(collection, 0, NULL);
2754 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2756 element = (void *)0xdeadbeef;
2757 hr = IMFCollection_GetElement(collection, 0, &element);
2758 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2759 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2761 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2762 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2764 element = (void *)0xdeadbeef;
2765 hr = IMFCollection_RemoveElement(collection, 0, &element);
2766 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2767 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2769 hr = IMFCollection_RemoveAllElements(collection);
2770 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2772 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2773 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2775 count = 0;
2776 hr = IMFCollection_GetElementCount(collection, &count);
2777 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2778 ok(count == 1, "Unexpected count %u.\n", count);
2780 hr = IMFCollection_AddElement(collection, NULL);
2781 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2783 count = 0;
2784 hr = IMFCollection_GetElementCount(collection, &count);
2785 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2786 ok(count == 2, "Unexpected count %u.\n", count);
2788 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2789 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2791 count = 0;
2792 hr = IMFCollection_GetElementCount(collection, &count);
2793 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2794 ok(count == 11, "Unexpected count %u.\n", count);
2796 hr = IMFCollection_GetElement(collection, 0, &element);
2797 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2798 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2799 IUnknown_Release(element);
2801 hr = IMFCollection_GetElement(collection, 1, &element);
2802 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2803 ok(!element, "Unexpected element.\n");
2805 hr = IMFCollection_GetElement(collection, 2, &element);
2806 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2807 ok(!element, "Unexpected element.\n");
2809 hr = IMFCollection_GetElement(collection, 10, &element);
2810 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2811 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2812 IUnknown_Release(element);
2814 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2815 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2817 hr = IMFCollection_GetElement(collection, 0, &element);
2818 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2820 hr = IMFCollection_RemoveAllElements(collection);
2821 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2823 count = 1;
2824 hr = IMFCollection_GetElementCount(collection, &count);
2825 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2826 ok(count == 0, "Unexpected count %u.\n", count);
2828 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2829 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2831 IMFCollection_Release(collection);
2834 static void test_MFHeapAlloc(void)
2836 void *res;
2838 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2839 ok(res != NULL, "MFHeapAlloc failed.\n");
2841 MFHeapFree(res);
2844 static void test_scheduled_items(void)
2846 struct test_callback callback;
2847 IMFAsyncResult *result;
2848 MFWORKITEM_KEY key, key2;
2849 HRESULT hr;
2851 init_test_callback(&callback);
2853 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2854 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2856 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2857 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2859 hr = MFCancelWorkItem(key);
2860 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2862 hr = MFCancelWorkItem(key);
2863 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2865 if (!pMFPutWaitingWorkItem)
2867 win_skip("Waiting items are not supported.\n");
2868 return;
2871 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2872 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2874 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2875 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2877 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2878 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2880 hr = MFCancelWorkItem(key);
2881 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2883 hr = MFCancelWorkItem(key2);
2884 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2886 IMFAsyncResult_Release(result);
2888 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2889 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2891 hr = MFCancelWorkItem(key);
2892 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2894 hr = MFShutdown();
2895 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2898 static void test_serial_queue(void)
2900 static const DWORD queue_ids[] =
2902 MFASYNC_CALLBACK_QUEUE_STANDARD,
2903 MFASYNC_CALLBACK_QUEUE_RT,
2904 MFASYNC_CALLBACK_QUEUE_IO,
2905 MFASYNC_CALLBACK_QUEUE_TIMER,
2906 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2907 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2909 DWORD queue, serial_queue;
2910 unsigned int i;
2911 HRESULT hr;
2913 if (!pMFAllocateSerialWorkQueue)
2915 win_skip("Serial queues are not supported.\n");
2916 return;
2919 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2920 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2922 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2924 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2925 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2927 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2928 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2929 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2931 if (SUCCEEDED(hr))
2933 hr = MFUnlockWorkQueue(serial_queue);
2934 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2938 /* Chain them together. */
2939 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2940 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2942 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2943 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2945 hr = MFUnlockWorkQueue(serial_queue);
2946 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2948 hr = MFUnlockWorkQueue(queue);
2949 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2951 hr = MFShutdown();
2952 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2955 static LONG periodic_counter;
2956 static void CALLBACK periodic_callback(IUnknown *context)
2958 InterlockedIncrement(&periodic_counter);
2961 static void test_periodic_callback(void)
2963 DWORD period, key;
2964 HRESULT hr;
2966 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2967 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2969 period = 0;
2970 hr = MFGetTimerPeriodicity(&period);
2971 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2972 ok(period == 10, "Unexpected period %u.\n", period);
2974 if (!pMFAddPeriodicCallback)
2976 win_skip("Periodic callbacks are not supported.\n");
2977 hr = MFShutdown();
2978 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2979 return;
2982 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2984 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2985 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2986 ok(key != 0, "Unexpected key %#x.\n", key);
2988 Sleep(10 * period);
2990 hr = pMFRemovePeriodicCallback(key);
2991 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2993 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2995 hr = MFShutdown();
2996 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2999 static void test_event_queue(void)
3001 struct test_callback callback, callback2;
3002 IMFMediaEvent *event, *event2;
3003 IMFMediaEventQueue *queue;
3004 IMFAsyncResult *result;
3005 HRESULT hr;
3006 DWORD ret;
3008 init_test_callback(&callback);
3009 init_test_callback(&callback2);
3011 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3012 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3014 hr = MFCreateEventQueue(&queue);
3015 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
3017 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3018 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
3020 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3021 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3023 if (is_win8_plus)
3025 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3026 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3028 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3029 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3030 ok(event2 == event, "Unexpected event object.\n");
3031 IMFMediaEvent_Release(event2);
3033 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3034 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3036 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3037 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3038 IMFMediaEvent_Release(event2);
3041 /* Async case. */
3042 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3043 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3045 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3046 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
3048 /* Same callback, same state. */
3049 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3050 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3052 /* Same callback, different state. */
3053 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
3054 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3056 /* Different callback, same state. */
3057 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
3058 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3060 /* Different callback, different state. */
3061 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
3062 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3064 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
3066 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3067 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3069 ret = WaitForSingleObject(callback.event, 500);
3070 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
3072 CloseHandle(callback.event);
3074 IMFMediaEvent_Release(event);
3076 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3077 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
3079 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3080 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3082 /* Shutdown behavior. */
3083 hr = IMFMediaEventQueue_Shutdown(queue);
3084 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3086 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3087 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3089 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3090 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3091 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3092 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3093 IMFMediaEvent_Release(event);
3095 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3096 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3098 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3099 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3101 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
3102 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3104 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3105 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3107 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3108 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3109 IMFAsyncResult_Release(result);
3111 /* Already shut down. */
3112 hr = IMFMediaEventQueue_Shutdown(queue);
3113 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3115 IMFMediaEventQueue_Release(queue);
3117 hr = MFShutdown();
3118 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3121 static void test_presentation_descriptor(void)
3123 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3124 IMFPresentationDescriptor *pd, *pd2;
3125 IMFMediaType *media_type;
3126 unsigned int i;
3127 BOOL selected;
3128 UINT64 value;
3129 DWORD count;
3130 HRESULT hr;
3132 hr = MFCreateMediaType(&media_type);
3133 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3135 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3137 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3138 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3141 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3142 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
3144 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3145 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
3147 for (i = 0; i < count; ++i)
3149 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3150 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3151 ok(!selected, "Unexpected selected state.\n");
3152 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3153 IMFStreamDescriptor_Release(stream_desc2);
3156 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3157 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3159 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3160 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3162 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3163 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
3165 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3166 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3167 ok(!!selected, "Unexpected selected state.\n");
3168 IMFStreamDescriptor_Release(stream_desc2);
3170 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3171 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3173 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3174 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
3176 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3177 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3178 ok(!!selected, "Unexpected selected state.\n");
3179 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3180 IMFStreamDescriptor_Release(stream_desc2);
3182 value = 0;
3183 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3184 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3185 ok(value == 1, "Unexpected attribute value.\n");
3187 IMFPresentationDescriptor_Release(pd2);
3188 IMFPresentationDescriptor_Release(pd);
3190 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3192 IMFStreamDescriptor_Release(stream_desc[i]);
3195 /* Partially initialized array. */
3196 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3197 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3198 stream_desc[0] = NULL;
3200 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3201 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3203 IMFStreamDescriptor_Release(stream_desc[1]);
3204 IMFMediaType_Release(media_type);
3207 enum clock_action
3209 CLOCK_START,
3210 CLOCK_STOP,
3211 CLOCK_PAUSE,
3212 CLOCK_RESTART,
3215 static void test_system_time_source(void)
3217 static const struct clock_state_test
3219 enum clock_action action;
3220 MFCLOCK_STATE state;
3221 BOOL is_invalid;
3223 clock_state_change[] =
3225 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3226 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3227 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3228 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3229 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3230 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3231 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3232 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3233 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3234 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3235 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3236 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3237 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3238 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3239 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3240 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3241 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3243 IMFPresentationTimeSource *time_source, *time_source2;
3244 IMFClockStateSink *statesink;
3245 IMFClock *clock, *clock2;
3246 MFCLOCK_PROPERTIES props;
3247 MFCLOCK_STATE state;
3248 unsigned int i;
3249 MFTIME systime;
3250 LONGLONG time;
3251 DWORD value;
3252 HRESULT hr;
3254 hr = MFCreateSystemTimeSource(&time_source);
3255 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3257 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3258 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
3259 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3260 "Unexpected flags %#x.\n", value);
3262 value = 1;
3263 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3264 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3265 ok(value == 0, "Unexpected value %u.\n", value);
3267 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3268 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
3269 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3271 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3272 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
3274 /* State changes. */
3275 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3277 switch (clock_state_change[i].action)
3279 case CLOCK_STOP:
3280 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3281 break;
3282 case CLOCK_RESTART:
3283 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3284 break;
3285 case CLOCK_PAUSE:
3286 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3287 break;
3288 case CLOCK_START:
3289 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3290 break;
3291 default:
3294 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
3295 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3296 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
3297 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3300 IMFClockStateSink_Release(statesink);
3302 /* Properties. */
3303 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3304 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3306 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3307 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3309 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3310 wine_dbgstr_longlong(props.qwCorrelationRate));
3311 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3312 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3313 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3314 wine_dbgstr_longlong(props.qwClockFrequency));
3315 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3316 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3318 /* Underlying clock. */
3319 hr = MFCreateSystemTimeSource(&time_source2);
3320 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3321 EXPECT_REF(time_source2, 1);
3322 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3323 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3324 EXPECT_REF(time_source2, 1);
3325 EXPECT_REF(clock2, 2);
3327 EXPECT_REF(time_source, 1);
3328 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3329 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3330 EXPECT_REF(time_source, 1);
3331 EXPECT_REF(clock, 2);
3333 ok(clock != clock2, "Unexpected clock instance.\n");
3335 IMFPresentationTimeSource_Release(time_source2);
3336 IMFClock_Release(clock2);
3338 hr = IMFClock_GetClockCharacteristics(clock, &value);
3339 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
3340 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3341 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
3343 hr = IMFClock_GetContinuityKey(clock, &value);
3344 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
3345 ok(value == 0, "Unexpected key value %u.\n", value);
3347 hr = IMFClock_GetState(clock, 0, &state);
3348 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
3349 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3351 hr = IMFClock_GetProperties(clock, &props);
3352 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3354 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3355 wine_dbgstr_longlong(props.qwCorrelationRate));
3356 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3357 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3358 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3359 wine_dbgstr_longlong(props.qwClockFrequency));
3360 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3361 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3363 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3364 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
3365 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3367 IMFClock_Release(clock);
3369 /* Test returned time regarding specified rate and offset. */
3370 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3371 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3373 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3374 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
3375 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3377 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3378 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3379 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3381 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3382 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3384 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3385 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3386 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3388 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3389 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3391 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3392 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3393 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3394 wine_dbgstr_longlong(systime));
3396 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3397 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3399 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3400 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3401 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3403 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3404 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3406 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3407 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3408 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3409 wine_dbgstr_longlong(systime));
3411 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3412 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3414 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3415 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3416 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3417 wine_dbgstr_longlong(systime));
3419 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3420 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3422 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3423 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3424 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3426 /* Increased rate. */
3427 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3428 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
3430 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3431 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3433 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3434 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3435 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3436 wine_dbgstr_longlong(2 * systime));
3438 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
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 + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3444 wine_dbgstr_longlong(2 * systime));
3446 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3447 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3449 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3450 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3451 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3452 wine_dbgstr_longlong(systime));
3454 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3455 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3457 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3458 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3459 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3460 wine_dbgstr_longlong(systime));
3462 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3463 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3465 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3466 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3467 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3468 wine_dbgstr_longlong(systime));
3470 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3471 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3473 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3474 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3475 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3477 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3478 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3480 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3481 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3482 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3483 wine_dbgstr_longlong(2 * systime));
3485 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3486 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3488 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3489 ok(hr == S_OK, "Failed to start source, 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 == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3494 wine_dbgstr_longlong(2 * systime));
3496 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3497 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3499 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3500 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3501 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3502 wine_dbgstr_longlong(systime));
3504 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3505 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3507 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3508 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3509 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3510 wine_dbgstr_longlong(systime));
3512 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3513 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3515 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3516 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3517 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3518 wine_dbgstr_longlong(systime));
3520 IMFClockStateSink_Release(statesink);
3521 IMFPresentationTimeSource_Release(time_source);
3523 /* PRESENTATION_CURRENT_POSITION */
3524 hr = MFCreateSystemTimeSource(&time_source);
3525 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3527 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3528 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3530 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3531 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3532 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3533 wine_dbgstr_longlong(systime));
3535 /* INVALID -> RUNNING */
3536 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3537 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3539 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3540 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3541 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3542 wine_dbgstr_longlong(systime));
3544 /* RUNNING -> RUNNING */
3545 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3546 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3548 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3549 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3550 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3551 wine_dbgstr_longlong(systime));
3553 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3554 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3556 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3557 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3558 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3559 wine_dbgstr_longlong(systime));
3561 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3562 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3564 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3565 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3566 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3567 wine_dbgstr_longlong(systime));
3569 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3570 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3572 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3573 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3574 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3575 wine_dbgstr_longlong(systime));
3577 /* STOPPED -> RUNNING */
3578 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3579 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3581 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3582 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3583 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3584 wine_dbgstr_longlong(systime));
3586 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3587 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3589 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3590 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3591 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3592 wine_dbgstr_longlong(systime));
3594 /* PAUSED -> RUNNING */
3595 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3596 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3598 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3599 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3600 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3601 wine_dbgstr_longlong(systime));
3603 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3604 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3606 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3607 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3608 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3609 wine_dbgstr_longlong(systime));
3611 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3612 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3614 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3615 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3616 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3617 wine_dbgstr_longlong(systime));
3619 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3620 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3622 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3623 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3624 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3625 wine_dbgstr_longlong(systime));
3627 IMFClockStateSink_Release(statesink);
3628 IMFPresentationTimeSource_Release(time_source);
3631 static void test_MFInvokeCallback(void)
3633 struct test_callback callback;
3634 IMFAsyncResult *result;
3635 MFASYNCRESULT *data;
3636 ULONG refcount;
3637 HRESULT hr;
3638 DWORD ret;
3640 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3641 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3643 init_test_callback(&callback);
3645 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3646 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3648 data = (MFASYNCRESULT *)result;
3649 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3650 ok(data->hEvent != NULL, "Failed to create event.\n");
3652 hr = MFInvokeCallback(result);
3653 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
3655 ret = WaitForSingleObject(data->hEvent, 100);
3656 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
3658 refcount = IMFAsyncResult_Release(result);
3659 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3661 hr = MFShutdown();
3662 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3665 static void test_stream_descriptor(void)
3667 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3668 IMFMediaTypeHandler *type_handler;
3669 IMFStreamDescriptor *stream_desc;
3670 GUID major_type;
3671 DWORD id, count;
3672 unsigned int i;
3673 HRESULT hr;
3675 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3676 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3678 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3680 hr = MFCreateMediaType(&media_types[i]);
3681 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3684 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3685 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3687 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3688 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3690 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3691 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
3692 ok(id == 123, "Unexpected id %#x.\n", id);
3694 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3695 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3697 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3698 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3699 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3701 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3702 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3704 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3705 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3707 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3709 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3710 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3711 ok(media_type == media_types[i], "Unexpected object.\n");
3713 if (SUCCEEDED(hr))
3714 IMFMediaType_Release(media_type);
3717 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
3718 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3720 /* IsMediaTypeSupported() */
3722 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3723 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3725 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
3726 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3728 hr = MFCreateMediaType(&media_type);
3729 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3731 hr = MFCreateMediaType(&media_type3);
3732 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3734 media_type2 = (void *)0xdeadbeef;
3735 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3736 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3737 ok(!media_type2, "Unexpected pointer.\n");
3739 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3740 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3742 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3743 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3745 media_type2 = (void *)0xdeadbeef;
3746 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3747 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3748 ok(!media_type2, "Unexpected pointer.\n");
3750 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3751 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3753 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3754 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3756 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3757 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3758 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
3760 /* Mismatching major types. */
3761 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3762 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3764 media_type2 = (void *)0xdeadbeef;
3765 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3766 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3767 ok(!media_type2, "Unexpected pointer.\n");
3769 /* Subtype missing. */
3770 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3771 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3773 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3774 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3776 media_type2 = (void *)0xdeadbeef;
3777 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3778 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3779 ok(!media_type2, "Unexpected pointer.\n");
3781 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3782 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3784 media_type2 = (void *)0xdeadbeef;
3785 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3786 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3787 ok(!media_type2, "Unexpected pointer.\n");
3789 /* Mismatching subtype. */
3790 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3791 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3793 media_type2 = (void *)0xdeadbeef;
3794 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3795 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3796 ok(!media_type2, "Unexpected pointer.\n");
3798 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3799 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3800 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3802 IMFMediaTypeHandler_Release(type_handler);
3803 IMFStreamDescriptor_Release(stream_desc);
3805 /* IsMediaTypeSupported() for unset current type. */
3806 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3807 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3809 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3810 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3812 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
3813 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3815 /* Initialize one from initial type set. */
3816 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
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_type3, &media_type2);
3821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3822 ok(!media_type2, "Unexpected pointer.\n");
3824 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3825 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3827 media_type2 = (void *)0xdeadbeef;
3828 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3829 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3830 ok(!media_type2, "Unexpected pointer.\n");
3832 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3833 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3835 media_type2 = (void *)0xdeadbeef;
3836 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3837 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3838 ok(!media_type2, "Unexpected pointer.\n");
3840 /* Now set current type that's not compatible. */
3841 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3842 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3844 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3845 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3847 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
3848 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3850 media_type2 = (void *)0xdeadbeef;
3851 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3852 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3853 ok(!media_type2, "Unexpected pointer.\n");
3855 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
3856 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3858 media_type2 = (void *)0xdeadbeef;
3859 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3860 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3861 ok(!media_type2, "Unexpected pointer.\n");
3863 IMFMediaType_Release(media_type);
3864 IMFMediaType_Release(media_type3);
3866 IMFMediaTypeHandler_Release(type_handler);
3868 IMFStreamDescriptor_Release(stream_desc);
3870 /* Major type is returned for first entry. */
3871 hr = MFCreateMediaType(&media_types[0]);
3872 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3873 hr = MFCreateMediaType(&media_types[1]);
3874 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3876 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3877 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3878 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3881 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
3882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3884 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3885 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3887 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3888 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3889 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3891 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3892 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3893 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3894 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3896 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3897 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3898 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3900 IMFMediaType_Release(media_types[0]);
3901 IMFMediaType_Release(media_types[1]);
3903 IMFMediaTypeHandler_Release(type_handler);
3904 IMFStreamDescriptor_Release(stream_desc);
3907 static void test_MFCalculateImageSize(void)
3909 static const struct image_size_test
3911 const GUID *subtype;
3912 UINT32 width;
3913 UINT32 height;
3914 UINT32 size;
3915 UINT32 plane_size; /* Matches image size when 0. */
3917 image_size_tests[] =
3919 { &MFVideoFormat_RGB8, 3, 5, 20 },
3920 { &MFVideoFormat_RGB8, 1, 1, 4 },
3921 { &MFVideoFormat_RGB555, 3, 5, 40 },
3922 { &MFVideoFormat_RGB555, 1, 1, 4 },
3923 { &MFVideoFormat_RGB565, 3, 5, 40 },
3924 { &MFVideoFormat_RGB565, 1, 1, 4 },
3925 { &MFVideoFormat_RGB24, 3, 5, 60 },
3926 { &MFVideoFormat_RGB24, 1, 1, 4 },
3927 { &MFVideoFormat_RGB32, 3, 5, 60 },
3928 { &MFVideoFormat_RGB32, 1, 1, 4 },
3929 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3930 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3931 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3932 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3933 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3934 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3936 /* YUV */
3937 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
3938 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
3939 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
3940 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
3941 { &MFVideoFormat_NV12, 4, 2, 12 },
3942 { &MFVideoFormat_NV12, 320, 240, 115200 },
3943 { &MFVideoFormat_AYUV, 1, 1, 4 },
3944 { &MFVideoFormat_AYUV, 2, 1, 8 },
3945 { &MFVideoFormat_AYUV, 1, 2, 8 },
3946 { &MFVideoFormat_AYUV, 4, 3, 48 },
3947 { &MFVideoFormat_AYUV, 320, 240, 307200 },
3948 { &MFVideoFormat_IMC1, 1, 1, 4 },
3949 { &MFVideoFormat_IMC1, 2, 1, 4 },
3950 { &MFVideoFormat_IMC1, 1, 2, 8 },
3951 { &MFVideoFormat_IMC1, 4, 3, 24 },
3952 { &MFVideoFormat_IMC1, 320, 240, 153600 },
3953 { &MFVideoFormat_IMC3, 1, 1, 4 },
3954 { &MFVideoFormat_IMC3, 2, 1, 4 },
3955 { &MFVideoFormat_IMC3, 1, 2, 8 },
3956 { &MFVideoFormat_IMC3, 4, 3, 24 },
3957 { &MFVideoFormat_IMC3, 320, 240, 153600 },
3958 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
3959 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
3960 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
3961 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
3962 { &MFVideoFormat_IMC2, 4, 2, 12 },
3963 { &MFVideoFormat_IMC2, 320, 240, 115200 },
3964 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
3965 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
3966 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
3967 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
3968 { &MFVideoFormat_IMC4, 4, 2, 12 },
3969 { &MFVideoFormat_IMC4, 320, 240, 115200 },
3970 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
3971 { &MFVideoFormat_YV12, 2, 1, 3 },
3972 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
3973 { &MFVideoFormat_YV12, 4, 3, 18 },
3974 { &MFVideoFormat_YV12, 320, 240, 115200 },
3976 { &MFVideoFormat_I420, 1, 1, 3, 1 },
3977 { &MFVideoFormat_I420, 2, 1, 3 },
3978 { &MFVideoFormat_I420, 1, 2, 6, 3 },
3979 { &MFVideoFormat_I420, 4, 3, 18 },
3980 { &MFVideoFormat_I420, 320, 240, 115200 },
3982 { &MFVideoFormat_YUY2, 2, 1, 4 },
3983 { &MFVideoFormat_YUY2, 4, 3, 24 },
3984 { &MFVideoFormat_YUY2, 128, 128, 32768 },
3985 { &MFVideoFormat_YUY2, 320, 240, 153600 },
3987 { &MFVideoFormat_UYVY, 2, 1, 4 },
3988 { &MFVideoFormat_UYVY, 4, 3, 24 },
3989 { &MFVideoFormat_UYVY, 128, 128, 32768 },
3990 { &MFVideoFormat_UYVY, 320, 240, 153600 },
3992 unsigned int i;
3993 UINT32 size;
3994 HRESULT hr;
3996 if (!pMFGetPlaneSize)
3997 win_skip("MFGetPlaneSize() is not available.\n");
3999 size = 1;
4000 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
4001 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
4002 ok(size == 0, "Unexpected size %u.\n", size);
4004 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
4006 const struct image_size_test *ptr = &image_size_tests[i];
4008 /* Those are supported since Win10. */
4009 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
4010 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
4012 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4013 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
4014 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4015 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4017 if (pMFGetPlaneSize)
4019 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4021 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4022 ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
4023 ok(size == plane_size, "%u: unexpected plane size %u, expected %u.\n", i, size, plane_size);
4028 static void test_MFCompareFullToPartialMediaType(void)
4030 IMFMediaType *full_type, *partial_type;
4031 HRESULT hr;
4032 BOOL ret;
4034 hr = MFCreateMediaType(&full_type);
4035 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4037 hr = MFCreateMediaType(&partial_type);
4038 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4040 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4041 ok(!ret, "Unexpected result %d.\n", ret);
4043 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4044 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4046 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4047 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4049 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4050 ok(ret, "Unexpected result %d.\n", ret);
4052 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4053 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4055 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4056 ok(ret, "Unexpected result %d.\n", ret);
4058 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4059 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4061 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4062 ok(!ret, "Unexpected result %d.\n", ret);
4064 IMFMediaType_Release(full_type);
4065 IMFMediaType_Release(partial_type);
4068 static void test_attributes_serialization(void)
4070 static const UINT8 blob[] = {1,2,3};
4071 IMFAttributes *attributes, *dest;
4072 UINT32 size, count, value32;
4073 double value_dbl;
4074 UINT64 value64;
4075 UINT8 *buffer;
4076 IUnknown *obj;
4077 HRESULT hr;
4078 WCHAR *str;
4079 GUID guid;
4081 hr = MFCreateAttributes(&attributes, 0);
4082 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4084 hr = MFCreateAttributes(&dest, 0);
4085 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4087 hr = MFGetAttributesAsBlobSize(attributes, &size);
4088 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4089 ok(size == 8, "Got size %u.\n", size);
4091 buffer = heap_alloc(size);
4093 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4094 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4096 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4097 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
4099 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4100 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4102 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4103 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4105 hr = MFInitAttributesFromBlob(dest, buffer, size);
4106 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4108 /* Previous items are cleared. */
4109 hr = IMFAttributes_GetCount(dest, &count);
4110 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
4111 ok(count == 0, "Unexpected count %u.\n", count);
4113 heap_free(buffer);
4115 /* Set some attributes of various types. */
4116 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4117 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4118 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4119 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4120 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4121 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4122 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4124 hr = MFGetAttributesAsBlobSize(attributes, &size);
4125 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4126 ok(size > 8, "Got unexpected size %u.\n", size);
4128 buffer = heap_alloc(size);
4129 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4130 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4131 hr = MFInitAttributesFromBlob(dest, buffer, size);
4132 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4133 heap_free(buffer);
4135 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4136 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
4137 ok(value32 == 456, "Unexpected value %u.\n", value32);
4138 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4139 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
4140 ok(value64 == 123, "Unexpected value.\n");
4141 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4142 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
4143 ok(value_dbl == 0.5, "Unexpected value.\n");
4144 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4145 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4146 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4147 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
4148 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4149 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4150 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
4151 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4152 CoTaskMemFree(str);
4153 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4154 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
4155 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4156 CoTaskMemFree(buffer);
4158 IMFAttributes_Release(attributes);
4159 IMFAttributes_Release(dest);
4162 static void test_wrapped_media_type(void)
4164 IMFMediaType *mediatype, *mediatype2;
4165 UINT32 count, type;
4166 HRESULT hr;
4167 GUID guid;
4169 hr = MFCreateMediaType(&mediatype);
4170 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4172 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4173 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4175 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4176 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4177 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4178 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4180 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4181 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
4183 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4184 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
4186 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4187 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4188 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4190 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4191 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
4192 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4194 hr = IMFMediaType_GetCount(mediatype2, &count);
4195 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
4196 ok(count == 3, "Unexpected count %u.\n", count);
4198 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4199 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
4200 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4202 IMFMediaType_Release(mediatype);
4204 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4205 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
4207 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4208 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4209 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4211 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4212 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4214 IMFMediaType_Release(mediatype);
4215 IMFMediaType_Release(mediatype2);
4218 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4220 WAVEFORMATEXTENSIBLE *format_ext;
4221 IMFMediaType *mediatype;
4222 WAVEFORMATEX *format;
4223 UINT32 size;
4224 HRESULT hr;
4226 hr = MFCreateMediaType(&mediatype);
4227 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4229 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4230 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4232 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4233 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4235 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4236 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4238 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4239 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4241 /* Audio/PCM */
4242 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4243 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4244 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4245 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4247 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4248 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4249 ok(format != NULL, "Expected format structure.\n");
4250 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4251 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
4252 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4253 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
4254 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
4255 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4256 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4257 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4258 CoTaskMemFree(format);
4260 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4261 MFWaveFormatExConvertFlag_ForceExtensible);
4262 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4263 ok(format_ext != NULL, "Expected format structure.\n");
4264 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4265 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4266 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4267 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
4268 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
4269 format_ext->Format.nAvgBytesPerSec);
4270 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4271 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4272 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4273 format_ext->Format.cbSize);
4274 CoTaskMemFree(format_ext);
4276 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4277 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4278 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4279 CoTaskMemFree(format);
4281 IMFMediaType_Release(mediatype);
4284 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4286 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4287 IMFByteStream *stream;
4288 IUnknown *object;
4289 HRESULT hr;
4291 ok(!!result, "Unexpected result object.\n");
4293 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4295 hr = IMFAsyncResult_GetObject(result, &object);
4296 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4298 hr = MFEndCreateFile(result, &stream);
4299 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
4300 IMFByteStream_Release(stream);
4302 SetEvent(callback->event);
4304 return S_OK;
4307 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4309 testcallback_QueryInterface,
4310 testcallback_AddRef,
4311 testcallback_Release,
4312 testcallback_GetParameters,
4313 test_create_file_callback_Invoke,
4316 static void test_async_create_file(void)
4318 struct test_callback callback = { { &test_create_file_callback_vtbl } };
4319 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4320 IUnknown *cancel_cookie;
4321 HRESULT hr;
4322 BOOL ret;
4324 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4325 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
4327 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
4329 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4330 GetTempFileNameW(pathW, NULL, 0, fileW);
4332 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4333 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
4334 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
4335 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4337 WaitForSingleObject(callback.event, INFINITE);
4339 IUnknown_Release(cancel_cookie);
4341 CloseHandle(callback.event);
4343 hr = MFShutdown();
4344 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4346 ret = DeleteFileW(fileW);
4347 ok(ret, "Failed to delete test file.\n");
4350 struct activate_object
4352 IMFActivate IMFActivate_iface;
4353 LONG refcount;
4356 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4358 if (IsEqualIID(riid, &IID_IMFActivate) ||
4359 IsEqualIID(riid, &IID_IMFAttributes) ||
4360 IsEqualIID(riid, &IID_IUnknown))
4362 *obj = iface;
4363 IMFActivate_AddRef(iface);
4364 return S_OK;
4367 *obj = NULL;
4368 return E_NOINTERFACE;
4371 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4373 return 2;
4376 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4378 return 1;
4381 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4383 return E_NOTIMPL;
4386 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4388 return E_NOTIMPL;
4391 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4393 return E_NOTIMPL;
4396 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4397 BOOL *result)
4399 return E_NOTIMPL;
4402 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4404 return E_NOTIMPL;
4407 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4409 return E_NOTIMPL;
4412 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4414 return E_NOTIMPL;
4417 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4419 return E_NOTIMPL;
4422 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4424 return E_NOTIMPL;
4427 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4428 UINT32 size, UINT32 *length)
4430 return E_NOTIMPL;
4433 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4434 WCHAR **value, UINT32 *length)
4436 return E_NOTIMPL;
4439 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4441 return E_NOTIMPL;
4444 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4445 UINT32 bufsize, UINT32 *blobsize)
4447 return E_NOTIMPL;
4450 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4452 return E_NOTIMPL;
4455 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4457 return E_NOTIMPL;
4460 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4462 return E_NOTIMPL;
4465 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4467 return E_NOTIMPL;
4470 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4472 return E_NOTIMPL;
4475 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4477 return E_NOTIMPL;
4480 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4482 return E_NOTIMPL;
4485 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4487 return E_NOTIMPL;
4490 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4492 return E_NOTIMPL;
4495 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4497 return E_NOTIMPL;
4500 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4502 return E_NOTIMPL;
4505 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4507 return E_NOTIMPL;
4510 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4512 return E_NOTIMPL;
4515 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4517 return E_NOTIMPL;
4520 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4522 return E_NOTIMPL;
4525 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4527 return E_NOTIMPL;
4530 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4532 return E_NOTIMPL;
4535 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4537 return E_NOTIMPL;
4540 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4542 return E_NOTIMPL;
4545 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4547 return E_NOTIMPL;
4550 static const IMFActivateVtbl activate_object_vtbl =
4552 activate_object_QueryInterface,
4553 activate_object_AddRef,
4554 activate_object_Release,
4555 activate_object_GetItem,
4556 activate_object_GetItemType,
4557 activate_object_CompareItem,
4558 activate_object_Compare,
4559 activate_object_GetUINT32,
4560 activate_object_GetUINT64,
4561 activate_object_GetDouble,
4562 activate_object_GetGUID,
4563 activate_object_GetStringLength,
4564 activate_object_GetString,
4565 activate_object_GetAllocatedString,
4566 activate_object_GetBlobSize,
4567 activate_object_GetBlob,
4568 activate_object_GetAllocatedBlob,
4569 activate_object_GetUnknown,
4570 activate_object_SetItem,
4571 activate_object_DeleteItem,
4572 activate_object_DeleteAllItems,
4573 activate_object_SetUINT32,
4574 activate_object_SetUINT64,
4575 activate_object_SetDouble,
4576 activate_object_SetGUID,
4577 activate_object_SetString,
4578 activate_object_SetBlob,
4579 activate_object_SetUnknown,
4580 activate_object_LockStore,
4581 activate_object_UnlockStore,
4582 activate_object_GetCount,
4583 activate_object_GetItemByIndex,
4584 activate_object_CopyAllItems,
4585 activate_object_ActivateObject,
4586 activate_object_ShutdownObject,
4587 activate_object_DetachObject,
4590 static void test_local_handlers(void)
4592 IMFActivate local_activate = { &activate_object_vtbl };
4593 static const WCHAR localW[] = L"local";
4594 HRESULT hr;
4596 if (!pMFRegisterLocalSchemeHandler)
4598 win_skip("Local handlers are not supported.\n");
4599 return;
4602 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4603 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4605 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4606 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4608 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4609 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4611 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4612 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4614 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4615 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4617 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4618 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4620 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4621 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4623 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4624 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4626 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4627 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4629 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4630 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4633 static void test_create_property_store(void)
4635 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4636 IPropertyStore *store, *store2;
4637 PROPVARIANT value = {0};
4638 PROPERTYKEY key;
4639 ULONG refcount;
4640 DWORD count;
4641 HRESULT hr;
4643 hr = CreatePropertyStore(NULL);
4644 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4646 hr = CreatePropertyStore(&store);
4647 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4649 hr = CreatePropertyStore(&store2);
4650 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4651 ok(store2 != store, "Expected different store objects.\n");
4652 IPropertyStore_Release(store2);
4654 check_interface(store, &IID_IPropertyStoreCache, FALSE);
4655 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
4657 hr = IPropertyStore_GetCount(store, NULL);
4658 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4660 count = 0xdeadbeef;
4661 hr = IPropertyStore_GetCount(store, &count);
4662 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4663 ok(!count, "Unexpected count %u.\n", count);
4665 hr = IPropertyStore_Commit(store);
4666 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4668 hr = IPropertyStore_GetAt(store, 0, &key);
4669 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4671 hr = IPropertyStore_GetValue(store, NULL, &value);
4672 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4674 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
4675 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4677 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4678 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4680 memset(&value, 0, sizeof(PROPVARIANT));
4681 value.vt = VT_I4;
4682 value.lVal = 0xdeadbeef;
4683 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4684 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4686 if (0)
4688 /* crashes on Windows */
4689 hr = IPropertyStore_SetValue(store, NULL, &value);
4690 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4693 hr = IPropertyStore_GetCount(store, &count);
4694 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4695 ok(count == 1, "Unexpected count %u.\n", count);
4697 hr = IPropertyStore_Commit(store);
4698 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4700 hr = IPropertyStore_GetAt(store, 0, &key);
4701 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4702 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
4704 hr = IPropertyStore_GetAt(store, 1, &key);
4705 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4707 memset(&value, 0xcc, sizeof(PROPVARIANT));
4708 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4709 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4710 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
4711 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
4713 memset(&value, 0, sizeof(PROPVARIANT));
4714 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4715 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4717 hr = IPropertyStore_GetCount(store, &count);
4718 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4719 ok(count == 1, "Unexpected count %u.\n", count);
4721 memset(&value, 0xcc, sizeof(PROPVARIANT));
4722 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4723 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4724 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
4725 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
4727 refcount = IPropertyStore_Release(store);
4728 ok(!refcount, "Unexpected refcount %u.\n", refcount);
4731 struct test_thread_param
4733 IMFDXGIDeviceManager *manager;
4734 HANDLE handle;
4735 BOOL lock;
4738 static DWORD WINAPI test_device_manager_thread(void *arg)
4740 struct test_thread_param *param = arg;
4741 ID3D11Device *device;
4742 HRESULT hr;
4744 if (param->lock)
4746 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
4747 (void **)&device, FALSE);
4748 if (SUCCEEDED(hr))
4749 ID3D11Device_Release(device);
4751 else
4752 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
4754 return hr;
4757 static void test_dxgi_device_manager(void)
4759 IMFDXGIDeviceManager *manager, *manager2;
4760 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
4761 struct test_thread_param param;
4762 HANDLE handle1, handle, thread;
4763 UINT token, token2;
4764 IUnknown *unk;
4765 HRESULT hr;
4767 if (!pMFCreateDXGIDeviceManager)
4769 win_skip("MFCreateDXGIDeviceManager not found.\n");
4770 return;
4773 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
4774 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4776 token = 0;
4777 hr = pMFCreateDXGIDeviceManager(&token, NULL);
4778 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4779 ok(!token, "got wrong token: %u.\n", token);
4781 hr = pMFCreateDXGIDeviceManager(&token, &manager);
4782 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4783 EXPECT_REF(manager, 1);
4784 ok(!!token, "got wrong token: %u.\n", token);
4786 Sleep(50);
4787 token2 = 0;
4788 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
4789 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4790 EXPECT_REF(manager2, 1);
4791 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
4792 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
4793 EXPECT_REF(manager, 1);
4795 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4796 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4798 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4799 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4801 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
4802 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4804 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
4805 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
4806 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4807 EXPECT_REF(d3d11_dev, 1);
4809 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
4810 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4811 EXPECT_REF(d3d11_dev, 1);
4813 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
4814 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4816 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4817 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4818 EXPECT_REF(manager, 1);
4819 EXPECT_REF(d3d11_dev, 2);
4821 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
4822 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4823 EXPECT_REF(manager2, 1);
4824 EXPECT_REF(d3d11_dev, 2);
4826 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4827 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4828 EXPECT_REF(manager, 1);
4829 EXPECT_REF(d3d11_dev, 2);
4831 /* GetVideoService() on device change. */
4832 handle = NULL;
4833 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4834 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4835 ok(!!handle, "Unexpected handle value %p.\n", handle);
4837 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
4838 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
4839 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4840 EXPECT_REF(d3d11_dev2, 1);
4841 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
4842 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4843 EXPECT_REF(manager, 1);
4844 EXPECT_REF(d3d11_dev2, 2);
4845 EXPECT_REF(d3d11_dev, 1);
4847 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4848 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr);
4850 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4851 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4853 handle = NULL;
4854 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4855 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4856 ok(!!handle, "Unexpected handle value %p.\n", handle);
4858 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4859 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4861 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4862 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4863 IUnknown_Release(unk);
4865 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
4866 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4867 IUnknown_Release(unk);
4869 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
4870 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4871 IUnknown_Release(unk);
4873 handle1 = NULL;
4874 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4875 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4876 ok(handle != handle1, "Unexpected handle.\n");
4878 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4881 /* Already closed. */
4882 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4883 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4885 handle = NULL;
4886 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4887 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4889 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4890 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4892 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
4893 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4895 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4896 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4897 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
4898 ID3D11Device_Release(device);
4900 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4901 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4903 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4904 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4906 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
4907 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4909 /* Locked with one handle, unlock with another. */
4910 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4911 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4913 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4914 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4916 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4917 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4919 ID3D11Device_Release(device);
4921 /* Closing unlocks the device. */
4922 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4923 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4925 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4926 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4927 ID3D11Device_Release(device);
4929 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4930 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4932 /* Open two handles. */
4933 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4934 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4936 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4937 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4939 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4940 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4941 ID3D11Device_Release(device);
4943 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4944 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4945 ID3D11Device_Release(device);
4947 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4948 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4950 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4951 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4953 param.manager = manager;
4954 param.handle = handle;
4955 param.lock = TRUE;
4956 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4957 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4958 GetExitCodeThread(thread, (DWORD *)&hr);
4959 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#x.\n", hr);
4960 CloseHandle(thread);
4962 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4963 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4965 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4966 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4968 /* Lock on main thread, unlock on another. */
4969 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4970 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4971 ID3D11Device_Release(device);
4973 param.manager = manager;
4974 param.handle = handle;
4975 param.lock = FALSE;
4976 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4977 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4978 GetExitCodeThread(thread, (DWORD *)&hr);
4979 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4980 CloseHandle(thread);
4982 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4983 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4985 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4988 IMFDXGIDeviceManager_Release(manager);
4989 EXPECT_REF(d3d11_dev2, 1);
4990 ID3D11Device_Release(d3d11_dev);
4991 ID3D11Device_Release(d3d11_dev2);
4992 IMFDXGIDeviceManager_Release(manager2);
4995 static void test_MFCreateTransformActivate(void)
4997 IMFActivate *activate;
4998 UINT32 count;
4999 HRESULT hr;
5001 if (!pMFCreateTransformActivate)
5003 win_skip("MFCreateTransformActivate() is not available.\n");
5004 return;
5007 hr = pMFCreateTransformActivate(&activate);
5008 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
5010 hr = IMFActivate_GetCount(activate, &count);
5011 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
5012 ok(!count, "Unexpected attribute count %u.\n", count);
5014 IMFActivate_Release(activate);
5017 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5019 if (IsEqualIID(riid, &IID_IClassFactory) ||
5020 IsEqualIID(riid, &IID_IUnknown))
5022 *obj = iface;
5023 IClassFactory_AddRef(iface);
5024 return S_OK;
5027 *obj = NULL;
5028 return E_NOINTERFACE;
5031 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5033 return 2;
5036 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5038 return 1;
5041 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5043 ok(0, "Unexpected call.\n");
5044 return E_NOTIMPL;
5047 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5049 return S_OK;
5052 static const IClassFactoryVtbl test_mft_factory_vtbl =
5054 test_mft_factory_QueryInterface,
5055 test_mft_factory_AddRef,
5056 test_mft_factory_Release,
5057 test_mft_factory_CreateInstance,
5058 test_mft_factory_LockServer,
5061 static void test_MFTRegisterLocal(void)
5063 IClassFactory test_factory = { &test_mft_factory_vtbl };
5064 MFT_REGISTER_TYPE_INFO input_types[1];
5065 IMFActivate **activate;
5066 UINT32 count, count2;
5067 HRESULT hr;
5069 if (!pMFTRegisterLocal)
5071 win_skip("MFTRegisterLocal() is not available.\n");
5072 return;
5075 input_types[0].guidMajorType = MFMediaType_Audio;
5076 input_types[0].guidSubtype = MFAudioFormat_PCM;
5077 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5078 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5080 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5081 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5083 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5085 ok(count > 0, "Unexpected count %u.\n", count);
5086 CoTaskMemFree(activate);
5088 hr = pMFTUnregisterLocal(&test_factory);
5089 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
5091 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5092 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5093 ok(count2 < count, "Unexpected count %u.\n", count2);
5094 CoTaskMemFree(activate);
5096 hr = pMFTUnregisterLocal(&test_factory);
5097 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5099 hr = pMFTUnregisterLocal(NULL);
5100 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5102 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5103 0, NULL);
5104 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5106 hr = pMFTUnregisterLocal(NULL);
5107 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5109 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5110 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5112 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5113 0, NULL);
5114 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5116 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5117 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5120 static void test_queue_com(void)
5122 static int system_queues[] =
5124 MFASYNC_CALLBACK_QUEUE_STANDARD,
5125 MFASYNC_CALLBACK_QUEUE_RT,
5126 MFASYNC_CALLBACK_QUEUE_IO,
5127 MFASYNC_CALLBACK_QUEUE_TIMER,
5128 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5129 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5132 static int user_queues[] =
5134 MF_STANDARD_WORKQUEUE,
5135 MF_WINDOW_WORKQUEUE,
5136 MF_MULTITHREADED_WORKQUEUE,
5139 char path_name[MAX_PATH];
5140 PROCESS_INFORMATION info;
5141 STARTUPINFOA startup;
5142 char **argv;
5143 int i;
5145 if (!pCoGetApartmentType)
5147 win_skip("CoGetApartmentType() is not available.\n");
5148 return;
5151 winetest_get_mainargs(&argv);
5153 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5155 memset(&startup, 0, sizeof(startup));
5156 startup.cb = sizeof(startup);
5157 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5158 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5159 "CreateProcess failed.\n" );
5160 wait_child_process(info.hProcess);
5161 CloseHandle(info.hProcess);
5162 CloseHandle(info.hThread);
5165 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5167 memset(&startup, 0, sizeof(startup));
5168 startup.cb = sizeof(startup);
5169 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5170 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5171 "CreateProcess failed.\n" );
5172 wait_child_process(info.hProcess);
5173 CloseHandle(info.hProcess);
5174 CloseHandle(info.hThread);
5178 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5180 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5181 APTTYPEQUALIFIER qualifier;
5182 APTTYPE com_type;
5183 HRESULT hr;
5185 hr = pCoGetApartmentType(&com_type, &qualifier);
5186 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr);
5187 if (SUCCEEDED(hr))
5189 todo_wine {
5190 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5191 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5192 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5193 else
5194 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5195 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5199 SetEvent(callback->event);
5200 return S_OK;
5203 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5205 testcallback_QueryInterface,
5206 testcallback_AddRef,
5207 testcallback_Release,
5208 testcallback_GetParameters,
5209 test_queue_com_state_callback_Invoke,
5212 static void test_queue_com_state(const char *name)
5214 struct test_callback callback = { { &test_queue_com_state_callback_vtbl } };
5215 DWORD queue, queue_type;
5216 HRESULT hr;
5218 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
5220 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5221 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
5223 if (name[0] == 's')
5225 callback.param = name[1] - '0';
5226 hr = MFPutWorkItem(callback.param, &callback.IMFAsyncCallback_iface, NULL);
5227 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5228 WaitForSingleObject(callback.event, INFINITE);
5230 else if (name[0] == 'u')
5232 queue_type = name[1] - '0';
5234 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5235 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5236 "Failed to allocate a queue of type %u, hr %#x.\n", queue_type, hr);
5238 if (SUCCEEDED(hr))
5240 callback.param = queue;
5241 hr = MFPutWorkItem(queue, &callback.IMFAsyncCallback_iface, NULL);
5242 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5243 WaitForSingleObject(callback.event, INFINITE);
5245 hr = MFUnlockWorkQueue(queue);
5246 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
5250 CloseHandle(callback.event);
5252 hr = MFShutdown();
5253 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
5256 static void test_MFGetStrideForBitmapInfoHeader(void)
5258 static const struct stride_test
5260 const GUID *subtype;
5261 unsigned int width;
5262 LONG stride;
5264 stride_tests[] =
5266 { &MFVideoFormat_RGB8, 3, -4 },
5267 { &MFVideoFormat_RGB8, 1, -4 },
5268 { &MFVideoFormat_RGB555, 3, -8 },
5269 { &MFVideoFormat_RGB555, 1, -4 },
5270 { &MFVideoFormat_RGB565, 3, -8 },
5271 { &MFVideoFormat_RGB565, 1, -4 },
5272 { &MFVideoFormat_RGB24, 3, -12 },
5273 { &MFVideoFormat_RGB24, 1, -4 },
5274 { &MFVideoFormat_RGB32, 3, -12 },
5275 { &MFVideoFormat_RGB32, 1, -4 },
5276 { &MFVideoFormat_ARGB32, 3, -12 },
5277 { &MFVideoFormat_ARGB32, 1, -4 },
5278 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5279 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5280 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5281 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5283 /* YUV */
5284 { &MFVideoFormat_NV12, 1, 1 },
5285 { &MFVideoFormat_NV12, 2, 2 },
5286 { &MFVideoFormat_NV12, 3, 3 },
5287 { &MFVideoFormat_AYUV, 1, 4 },
5288 { &MFVideoFormat_AYUV, 4, 16 },
5289 { &MFVideoFormat_AYUV, 5, 20 },
5290 { &MFVideoFormat_IMC1, 1, 4 },
5291 { &MFVideoFormat_IMC1, 2, 4 },
5292 { &MFVideoFormat_IMC1, 3, 8 },
5293 { &MFVideoFormat_IMC3, 1, 4 },
5294 { &MFVideoFormat_IMC3, 2, 4 },
5295 { &MFVideoFormat_IMC3, 3, 8 },
5296 { &MFVideoFormat_IMC2, 1, 1 },
5297 { &MFVideoFormat_IMC2, 2, 2 },
5298 { &MFVideoFormat_IMC2, 3, 3 },
5299 { &MFVideoFormat_IMC4, 1, 1 },
5300 { &MFVideoFormat_IMC4, 2, 2 },
5301 { &MFVideoFormat_IMC4, 3, 3 },
5302 { &MFVideoFormat_YV12, 1, 1 },
5303 { &MFVideoFormat_YV12, 2, 2 },
5304 { &MFVideoFormat_YV12, 3, 3 },
5305 { &MFVideoFormat_YV12, 320, 320 },
5306 { &MFVideoFormat_I420, 1, 1 },
5307 { &MFVideoFormat_I420, 2, 2 },
5308 { &MFVideoFormat_I420, 3, 3 },
5309 { &MFVideoFormat_I420, 320, 320 },
5311 unsigned int i;
5312 LONG stride;
5313 HRESULT hr;
5315 if (!pMFGetStrideForBitmapInfoHeader)
5317 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5318 return;
5321 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5322 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5324 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5326 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5327 ok(hr == S_OK, "%u: failed to get stride, hr %#x.\n", i, hr);
5328 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %d, expected %d.\n", i,
5329 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5333 static void test_MFCreate2DMediaBuffer(void)
5335 static const struct _2d_buffer_test
5337 unsigned int width;
5338 unsigned int height;
5339 unsigned int fourcc;
5340 unsigned int contiguous_length;
5341 int pitch;
5342 unsigned int plane_multiplier;
5343 } _2d_buffer_tests[] =
5345 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64 },
5346 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5347 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5348 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5350 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128 },
5351 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5352 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5353 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5354 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5355 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5357 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128, 2 },
5358 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128, 2 },
5359 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 2 },
5360 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128, 2 },
5362 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128, 2 },
5363 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128, 2 },
5364 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 2 },
5365 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128, 2 },
5367 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5368 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5369 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128 },
5371 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5372 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5373 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64 },
5375 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5376 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5377 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64 },
5379 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5380 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5381 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64 },
5383 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5384 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5385 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5387 unsigned int max_length, length, length2;
5388 BYTE *buffer_start, *data, *data2;
5389 IMF2DBuffer2 *_2dbuffer2;
5390 IMF2DBuffer *_2dbuffer;
5391 IMFMediaBuffer *buffer;
5392 int i, pitch, pitch2;
5393 HRESULT hr;
5394 BOOL ret;
5396 if (!pMFCreate2DMediaBuffer)
5398 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5399 return;
5402 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5403 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5405 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5406 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5408 /* YUV formats can't be bottom-up. */
5409 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5410 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5412 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5413 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5415 check_interface(buffer, &IID_IMFGetService, TRUE);
5416 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5418 /* Full backing buffer size, with 64 bytes per row alignment. */
5419 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5420 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5421 ok(max_length > 0, "Unexpected length %u.\n", max_length);
5423 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5424 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5425 ok(!length, "Unexpected length.\n");
5427 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5428 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
5430 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5431 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5432 ok(length == 10, "Unexpected length.\n");
5434 /* Linear lock/unlock. */
5436 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5437 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5439 /* Linear locking call returns plane size.*/
5440 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5441 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5442 ok(max_length == length, "Unexpected length.\n");
5444 length = 0;
5445 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5446 ok(max_length == length && length == 9, "Unexpected length %u.\n", length);
5448 /* Already locked */
5449 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5450 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5451 ok(data2 == data, "Unexpected pointer.\n");
5453 hr = IMFMediaBuffer_Unlock(buffer);
5454 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5456 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5457 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5459 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5460 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5462 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5463 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5464 ok(length == 9, "Unexpected length %u.\n", length);
5466 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5467 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5469 /* 2D lock. */
5470 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5471 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
5473 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5474 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5476 hr = IMFMediaBuffer_Unlock(buffer);
5477 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5479 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5480 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5482 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5483 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5485 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5486 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5488 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5489 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5491 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5492 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5493 ok(!!data, "Expected data pointer.\n");
5494 ok(pitch == 64, "Unexpected pitch %d.\n", pitch);
5496 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5497 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5498 ok(data == data2, "Expected data pointer.\n");
5500 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5501 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5503 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5504 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5506 /* Active 2D lock */
5507 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5508 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5510 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5511 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5513 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5514 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5516 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5517 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5519 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5520 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5522 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5523 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#x.\n", hr);
5525 if (SUCCEEDED(hr))
5527 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5528 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5530 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5531 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5533 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5534 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5536 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5537 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5539 /* Flags are ignored. */
5540 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5541 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5543 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, &length);
5544 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5546 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5547 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5549 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5550 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5552 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5553 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5555 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5556 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5558 IMF2DBuffer2_Release(_2dbuffer2);
5560 else
5561 win_skip("IMF2DBuffer2 is not supported.\n");
5563 IMF2DBuffer_Release(_2dbuffer);
5565 IMFMediaBuffer_Release(buffer);
5567 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5569 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5571 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5572 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5574 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5575 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5577 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5578 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5579 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %u for %u x %u, format %s.\n",
5580 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5582 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5583 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5584 ok(length == ptr->contiguous_length, "%d: unexpected linear buffer length %u for %u x %u, format %s.\n",
5585 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5587 hr = IMFMediaBuffer_Unlock(buffer);
5588 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5590 hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2);
5591 ok(hr == S_OK, "Failed to get plane size, hr %#x.\n", hr);
5592 if (ptr->plane_multiplier)
5593 length2 *= ptr->plane_multiplier;
5594 ok(length2 == length, "%d: contiguous length %u does not match plane size %u, %u x %u, format %s.\n", i, length,
5595 length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5597 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5598 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5600 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
5601 ok(hr == S_OK, "Failed to get scanline, hr %#x.\n", hr);
5602 ok(data2 == data, "Unexpected data pointer.\n");
5603 ok(pitch == pitch2, "Unexpected pitch.\n");
5605 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5606 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5608 ok(pitch == ptr->pitch, "%d: unexpected pitch %d, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
5609 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5611 ret = TRUE;
5612 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
5613 ok(hr == S_OK, "Failed to get format flag, hr %#x.\n", hr);
5614 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
5616 IMF2DBuffer_Release(_2dbuffer);
5618 IMFMediaBuffer_Release(buffer);
5622 static void test_MFCreateMediaBufferFromMediaType(void)
5624 static struct audio_buffer_test
5626 unsigned int duration;
5627 unsigned int min_length;
5628 unsigned int min_alignment;
5629 unsigned int block_alignment;
5630 unsigned int bytes_per_second;
5631 unsigned int buffer_length;
5632 } audio_tests[] =
5634 { 0, 0, 0, 4, 0, 20 },
5635 { 0, 16, 0, 4, 0, 20 },
5636 { 0, 0, 32, 4, 0, 36 },
5637 { 0, 64, 32, 4, 0, 64 },
5638 { 1, 0, 0, 4, 16, 36 },
5639 { 2, 0, 0, 4, 16, 52 },
5641 IMFMediaBuffer *buffer;
5642 UINT32 length;
5643 HRESULT hr;
5644 IMFMediaType *media_type;
5645 unsigned int i;
5647 if (!pMFCreateMediaBufferFromMediaType)
5649 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
5650 return;
5653 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
5654 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5656 hr = MFCreateMediaType(&media_type);
5657 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5659 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
5660 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5662 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
5664 const struct audio_buffer_test *ptr = &audio_tests[i];
5666 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
5667 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5669 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
5670 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5672 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
5673 ptr->min_alignment, &buffer);
5674 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr);
5675 if (FAILED(hr))
5676 break;
5678 check_interface(buffer, &IID_IMFGetService, FALSE);
5680 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5681 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5682 ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
5684 IMFMediaBuffer_Release(buffer);
5687 IMFMediaType_Release(media_type);
5690 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
5692 GUID guid, subtype;
5693 UINT32 value;
5694 HRESULT hr;
5696 hr = IMFMediaType_GetMajorType(mediatype, &guid);
5697 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
5698 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
5700 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
5701 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
5703 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
5705 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
5706 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5708 if (fex->dwChannelMask)
5710 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
5711 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5712 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
5715 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
5717 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
5718 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5719 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
5722 else
5724 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
5725 subtype.Data1 = format->wFormatTag;
5726 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5728 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
5729 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5730 ok(value, "Unexpected value.\n");
5733 if (format->nChannels)
5735 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
5736 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5737 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
5740 if (format->nSamplesPerSec)
5742 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
5743 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5744 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
5747 if (format->nAvgBytesPerSec)
5749 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
5750 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5751 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
5754 if (format->nBlockAlign)
5756 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
5757 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5758 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
5761 if (format->wBitsPerSample)
5763 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
5764 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5765 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
5768 /* Only set for uncompressed formats. */
5769 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
5770 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
5771 IsEqualGUID(&guid, &MFAudioFormat_PCM))
5773 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5774 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
5776 else
5777 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
5780 static void test_MFInitMediaTypeFromWaveFormatEx(void)
5782 static const WAVEFORMATEX waveformatex_tests[] =
5784 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
5785 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
5786 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
5787 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
5788 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
5789 { 1234, 0, 0, 0, 0, 0 },
5790 { WAVE_FORMAT_ALAW },
5791 { WAVE_FORMAT_CREATIVE_ADPCM },
5792 { WAVE_FORMAT_MPEGLAYER3 },
5793 { WAVE_FORMAT_MPEG_ADTS_AAC },
5794 { WAVE_FORMAT_ALAC },
5795 { WAVE_FORMAT_AMR_NB },
5796 { WAVE_FORMAT_AMR_WB },
5797 { WAVE_FORMAT_AMR_WP },
5798 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
5799 { WAVE_FORMAT_DRM },
5800 { WAVE_FORMAT_DTS },
5801 { WAVE_FORMAT_FLAC },
5802 { WAVE_FORMAT_MPEG },
5803 { WAVE_FORMAT_WMAVOICE9 },
5804 { WAVE_FORMAT_OPUS },
5805 { WAVE_FORMAT_WMAUDIO2 },
5806 { WAVE_FORMAT_WMAUDIO3 },
5807 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
5808 { WAVE_FORMAT_WMASPDIF },
5811 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
5812 WAVEFORMATEXTENSIBLE waveformatext;
5813 MPEGLAYER3WAVEFORMAT mp3format;
5814 IMFMediaType *mediatype;
5815 unsigned int i, size;
5816 HRESULT hr;
5818 hr = MFCreateMediaType(&mediatype);
5819 ok(hr == S_OK, "Failed to create mediatype, hr %#x.\n", hr);
5821 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
5823 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
5824 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#x.\n", i, waveformatex_tests[i].wFormatTag, hr);
5826 validate_media_type(mediatype, &waveformatex_tests[i]);
5828 waveformatext.Format = waveformatex_tests[i];
5829 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
5830 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
5831 waveformatext.Samples.wSamplesPerBlock = 123;
5832 waveformatext.dwChannelMask = 0x8;
5833 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
5834 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
5836 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
5837 ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr);
5839 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
5840 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
5842 validate_media_type(mediatype, &waveformatext.Format);
5845 /* MPEGLAYER3WAVEFORMAT */
5846 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
5847 mp3format.wfx.nChannels = 2;
5848 mp3format.wfx.nSamplesPerSec = 44100;
5849 mp3format.wfx.nAvgBytesPerSec = 16000;
5850 mp3format.wfx.nBlockAlign = 1;
5851 mp3format.wfx.wBitsPerSample = 0;
5852 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
5853 mp3format.wID = MPEGLAYER3_ID_MPEG;
5854 mp3format.fdwFlags = 0;
5855 mp3format.nBlockSize = 417;
5856 mp3format.nFramesPerBlock = 0;
5857 mp3format.nCodecDelay = 0;
5859 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
5860 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5862 validate_media_type(mediatype, &mp3format.wfx);
5863 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
5864 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5865 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
5866 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
5868 IMFMediaType_Release(mediatype);
5871 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
5873 MFVIDEOFORMAT *video_format;
5874 IMFMediaType *media_type;
5875 UINT32 size;
5876 HRESULT hr;
5878 hr = MFCreateMediaType(&media_type);
5879 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5881 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
5882 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5883 ok(!!video_format, "Unexpected format.\n");
5884 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
5885 CoTaskMemFree(video_format);
5887 IMFMediaType_Release(media_type);
5890 static void test_MFCreateDXSurfaceBuffer(void)
5892 IDirect3DSurface9 *backbuffer = NULL, *surface;
5893 IDirect3DSwapChain9 *swapchain;
5894 DWORD length, max_length;
5895 IDirect3DDevice9 *device;
5896 IMF2DBuffer2 *_2dbuffer2;
5897 IMFMediaBuffer *buffer;
5898 IMF2DBuffer *_2dbuffer;
5899 BYTE *data, *data2;
5900 IMFGetService *gs;
5901 IDirect3D9 *d3d;
5902 HWND window;
5903 HRESULT hr;
5904 LONG pitch;
5905 BOOL value;
5907 if (!pMFCreateDXSurfaceBuffer)
5909 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
5910 return;
5913 window = create_window();
5914 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5915 ok(!!d3d, "Failed to create a D3D object.\n");
5916 if (!(device = create_device(d3d, window)))
5918 skip("Failed to create a D3D device, skipping tests.\n");
5919 goto done;
5922 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
5923 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
5925 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5926 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
5927 ok(backbuffer != NULL, "The back buffer is NULL\n");
5929 IDirect3DSwapChain9_Release(swapchain);
5931 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
5932 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5934 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
5935 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5937 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5938 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
5939 check_interface(buffer, &IID_IMFGetService, TRUE);
5941 /* Surface is accessible. */
5942 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
5943 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5944 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
5945 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5946 ok(surface == backbuffer, "Unexpected surface pointer.\n");
5947 IDirect3DSurface9_Release(surface);
5948 IMFGetService_Release(gs);
5950 max_length = 0;
5951 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5953 ok(!!max_length, "Unexpected length %u.\n", max_length);
5955 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5956 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5957 ok(!length, "Unexpected length %u.\n", length);
5959 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
5960 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5962 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5963 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5964 ok(length == 2 * max_length, "Unexpected length %u.\n", length);
5966 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
5967 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5968 ok(length == max_length, "Unexpected length.\n");
5970 /* Unlock twice. */
5971 hr = IMFMediaBuffer_Unlock(buffer);
5972 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5974 hr = IMFMediaBuffer_Unlock(buffer);
5975 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5977 /* Lock twice. */
5978 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5979 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5981 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5982 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5983 ok(data == data2, "Unexpected pointer.\n");
5985 hr = IMFMediaBuffer_Unlock(buffer);
5986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5988 hr = IMFMediaBuffer_Unlock(buffer);
5989 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5991 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5992 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5994 /* Unlocked. */
5995 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5996 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5998 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5999 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6001 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
6002 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6004 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
6005 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
6007 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
6008 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6010 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6011 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6013 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6014 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6016 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6017 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6019 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6020 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6021 ok(!value, "Unexpected return value %d.\n", value);
6023 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6024 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6025 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6026 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6027 ok(length == max_length, "Unexpected length %u.\n", length);
6029 IMF2DBuffer_Release(_2dbuffer);
6031 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6032 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6034 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6035 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6036 ok(data == data2, "Unexpected scanline pointer.\n");
6037 memset(data, 0xab, 4);
6038 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6040 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6041 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6042 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6043 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6045 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6046 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6047 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6048 hr = IMFMediaBuffer_Unlock(buffer);
6049 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6051 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6052 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6053 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6055 IMF2DBuffer2_Release(_2dbuffer2);
6057 IMFMediaBuffer_Release(buffer);
6059 done:
6060 if (backbuffer)
6061 IDirect3DSurface9_Release(backbuffer);
6062 IDirect3D9_Release(d3d);
6063 DestroyWindow(window);
6066 static void test_MFCreateTrackedSample(void)
6068 IMFTrackedSample *tracked_sample;
6069 IMFSample *sample;
6070 IUnknown *unk;
6071 HRESULT hr;
6073 if (!pMFCreateTrackedSample)
6075 win_skip("MFCreateTrackedSample() is not available.\n");
6076 return;
6079 hr = pMFCreateTrackedSample(&tracked_sample);
6080 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6082 /* It's actually a sample. */
6083 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6086 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6087 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6088 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6089 IUnknown_Release(unk);
6091 IMFSample_Release(sample);
6093 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6095 IMFTrackedSample_Release(tracked_sample);
6098 static void test_MFFrameRateToAverageTimePerFrame(void)
6100 static const struct frame_rate_test
6102 unsigned int numerator;
6103 unsigned int denominator;
6104 UINT64 avgtime;
6105 } frame_rate_tests[] =
6107 { 60000, 1001, 166833 },
6108 { 30000, 1001, 333667 },
6109 { 24000, 1001, 417188 },
6110 { 60, 1, 166667 },
6111 { 30, 1, 333333 },
6112 { 50, 1, 200000 },
6113 { 25, 1, 400000 },
6114 { 24, 1, 416667 },
6116 { 39, 1, 256410 },
6117 { 120, 1, 83333 },
6119 unsigned int i;
6120 UINT64 avgtime;
6121 HRESULT hr;
6123 avgtime = 1;
6124 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6125 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6126 ok(!avgtime, "Unexpected frame time.\n");
6128 avgtime = 1;
6129 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6130 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6131 ok(!avgtime, "Unexpected frame time.\n");
6133 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6135 avgtime = 0;
6136 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6137 frame_rate_tests[i].denominator, &avgtime);
6138 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6139 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6140 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6144 static void test_MFMapDXGIFormatToDX9Format(void)
6146 static const struct format_pair
6148 DXGI_FORMAT dxgi_format;
6149 DWORD d3d9_format;
6151 formats_map[] =
6153 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6154 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6155 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6156 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6157 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6158 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6159 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6160 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6161 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6162 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6163 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6164 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6165 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6166 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6167 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6168 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6169 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6170 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6171 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6172 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6173 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6174 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6175 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6176 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6177 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6178 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6179 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6180 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6181 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6182 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6183 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6184 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6185 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6186 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6187 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6188 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6189 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6190 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6191 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6192 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6193 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6194 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6195 { DXGI_FORMAT_P8, D3DFMT_P8 },
6196 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6198 unsigned int i;
6199 DWORD format;
6201 if (!pMFMapDXGIFormatToDX9Format)
6203 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6204 return;
6207 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6209 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6210 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#x, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6214 static void test_MFMapDX9FormatToDXGIFormat(void)
6216 static const struct format_pair
6218 DXGI_FORMAT dxgi_format;
6219 DWORD d3d9_format;
6221 formats_map[] =
6223 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6224 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6225 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6226 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6227 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6228 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6229 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6230 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6231 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6232 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6233 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6234 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6235 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6236 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6237 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6238 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6239 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6240 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6241 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6242 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6243 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6244 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6245 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6246 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6247 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6248 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6249 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6250 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6251 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6252 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6253 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6254 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6255 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6256 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6257 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6258 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6259 { DXGI_FORMAT_P8, D3DFMT_P8 },
6260 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6262 DXGI_FORMAT format;
6263 unsigned int i;
6265 if (!pMFMapDX9FormatToDXGIFormat)
6267 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6268 return;
6271 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6273 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6274 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#x.\n",
6275 format, formats_map[i].d3d9_format);
6279 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6280 REFIID riid, void **obj)
6282 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6283 IsEqualIID(riid, &IID_IUnknown))
6285 *obj = iface;
6286 IMFVideoSampleAllocatorNotify_AddRef(iface);
6287 return S_OK;
6290 *obj = NULL;
6291 return E_NOINTERFACE;
6294 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6296 return 2;
6299 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6301 return 1;
6304 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6306 return E_NOTIMPL;
6309 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6311 test_notify_callback_QueryInterface,
6312 test_notify_callback_AddRef,
6313 test_notify_callback_Release,
6314 test_notify_callback_NotifyRelease,
6317 static IMFMediaType * create_video_type(const GUID *subtype)
6319 IMFMediaType *video_type;
6320 HRESULT hr;
6322 hr = MFCreateMediaType(&video_type);
6323 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6325 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6326 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6328 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6329 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6331 return video_type;
6334 static ID3D11Device *create_d3d11_device(void)
6336 static const D3D_FEATURE_LEVEL default_feature_level[] =
6338 D3D_FEATURE_LEVEL_11_0,
6339 D3D_FEATURE_LEVEL_10_1,
6340 D3D_FEATURE_LEVEL_10_0,
6342 const D3D_FEATURE_LEVEL *feature_level;
6343 unsigned int feature_level_count;
6344 ID3D11Device *device;
6346 feature_level = default_feature_level;
6347 feature_level_count = ARRAY_SIZE(default_feature_level);
6349 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6350 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6351 return device;
6352 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6353 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6354 return device;
6355 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6356 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6357 return device;
6359 return NULL;
6362 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
6363 const BYTE *data, unsigned int src_pitch)
6365 ID3D11DeviceContext *immediate_context;
6366 ID3D11Device *device;
6368 ID3D11Texture2D_GetDevice(texture, &device);
6369 ID3D11Device_GetImmediateContext(device, &immediate_context);
6371 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
6372 sub_resource_idx, NULL, data, src_pitch, 0);
6374 ID3D11DeviceContext_Release(immediate_context);
6375 ID3D11Device_Release(device);
6378 static void test_dxgi_surface_buffer(void)
6380 DWORD max_length, cur_length, length, color;
6381 IMFDXGIBuffer *dxgi_buffer;
6382 D3D11_TEXTURE2D_DESC desc;
6383 ID3D11Texture2D *texture;
6384 IMF2DBuffer *_2d_buffer;
6385 IMFMediaBuffer *buffer;
6386 ID3D11Device *device;
6387 BYTE buff[64 * 64 * 4];
6388 BYTE *data, *data2;
6389 LONG pitch, pitch2;
6390 UINT index, size;
6391 IUnknown *obj;
6392 HRESULT hr;
6394 if (!pMFCreateDXGISurfaceBuffer)
6396 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
6397 return;
6400 device = create_d3d11_device();
6402 memset(&desc, 0, sizeof(desc));
6403 desc.Width = 64;
6404 desc.Height = 64;
6405 desc.ArraySize = 1;
6406 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
6407 desc.SampleDesc.Count = 1;
6408 desc.SampleDesc.Quality = 0;
6410 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6411 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6413 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
6414 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6416 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6417 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6418 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6419 check_interface(buffer, &IID_IMFGetService, FALSE);
6421 max_length = 0;
6422 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6423 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6424 ok(!!max_length, "Unexpected length %u.\n", max_length);
6426 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6427 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6428 ok(!cur_length, "Unexpected length %u.\n", cur_length);
6430 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6431 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6433 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6434 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6435 ok(cur_length == 2 * max_length, "Unexpected length %u.\n", cur_length);
6437 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6438 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6440 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
6441 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6442 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
6443 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6444 ok(length == max_length, "Unexpected length %u.\n", length);
6445 IMF2DBuffer_Release(_2d_buffer);
6447 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6448 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6450 EXPECT_REF(texture, 2);
6451 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
6452 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6453 EXPECT_REF(texture, 3);
6454 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
6455 IUnknown_Release(obj);
6457 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
6458 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6460 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
6461 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6462 ok(index == 0, "Unexpected subresource index.\n");
6464 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6465 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6467 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6468 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6470 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6471 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#x.\n", hr);
6473 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
6474 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6476 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
6477 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6478 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
6479 IUnknown_Release(obj);
6481 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6482 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6484 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
6485 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6487 IMFDXGIBuffer_Release(dxgi_buffer);
6489 /* Texture updates. */
6490 color = get_d3d11_texture_color(texture, 0, 0);
6491 ok(!color, "Unexpected texture color %#x.\n", color);
6493 max_length = cur_length = 0;
6494 data = NULL;
6495 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6496 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6497 ok(max_length && max_length == cur_length, "Unexpected length %u.\n", max_length);
6498 if (data) *(DWORD *)data = ~0u;
6500 color = get_d3d11_texture_color(texture, 0, 0);
6501 ok(!color, "Unexpected texture color %#x.\n", color);
6503 hr = IMFMediaBuffer_Unlock(buffer);
6504 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6506 color = get_d3d11_texture_color(texture, 0, 0);
6507 ok(color == ~0u, "Unexpected texture color %#x.\n", color);
6509 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6510 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6511 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data);
6513 hr = IMFMediaBuffer_Unlock(buffer);
6514 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6516 /* Lock2D()/Unlock2D() */
6517 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6518 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6520 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6521 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6523 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6524 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6525 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6527 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6528 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6529 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6531 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6532 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6533 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
6535 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6536 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
6538 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6539 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6541 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6542 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6544 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6545 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6547 IMF2DBuffer_Release(_2d_buffer);
6548 IMFMediaBuffer_Release(buffer);
6550 /* Bottom up. */
6551 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
6552 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6554 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6555 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6557 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6558 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6559 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6561 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6562 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6563 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
6565 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6566 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6568 IMF2DBuffer_Release(_2d_buffer);
6569 IMFMediaBuffer_Release(buffer);
6571 ID3D11Texture2D_Release(texture);
6573 /* Subresource index 1. */
6574 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6575 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6577 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
6578 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6580 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6581 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6583 /* Pitch reflects top level. */
6584 memset(buff, 0, sizeof(buff));
6585 *(DWORD *)buff = 0xff00ff00;
6586 update_d3d11_texture(texture, 1, buff, 64 * 4);
6588 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6589 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6590 ok(pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6591 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#x.\n", *(DWORD *)data);
6593 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6594 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6596 IMF2DBuffer_Release(_2d_buffer);
6597 IMFMediaBuffer_Release(buffer);
6599 ID3D11Texture2D_Release(texture);
6601 ID3D11Device_Release(device);
6604 static void test_sample_allocator(void)
6606 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
6607 IMFMediaType *media_type, *video_type, *video_type2;
6608 IMFVideoSampleAllocatorCallback *allocator_cb;
6609 IMFVideoSampleAllocatorEx *allocatorex;
6610 IDirect3DDeviceManager9 *d3d9_manager;
6611 IMFVideoSampleAllocator *allocator;
6612 unsigned int i, buffer_count, token;
6613 IDirect3DDevice9 *d3d9_device;
6614 IMFDXGIDeviceManager *manager;
6615 IMFSample *sample, *sample2;
6616 IMFDXGIBuffer *dxgi_buffer;
6617 IMFAttributes *attributes;
6618 D3D11_TEXTURE2D_DESC desc;
6619 ID3D11Texture2D *texture;
6620 IMFMediaBuffer *buffer;
6621 ID3D11Device *device;
6622 LONG refcount, count;
6623 IDirect3D9 *d3d9;
6624 IUnknown *unk;
6625 HRESULT hr;
6626 BYTE *data;
6627 HWND window;
6628 static const unsigned int usage[] =
6630 D3D11_USAGE_DEFAULT,
6631 D3D11_USAGE_IMMUTABLE,
6632 D3D11_USAGE_DYNAMIC,
6633 D3D11_USAGE_STAGING,
6634 D3D11_USAGE_STAGING + 1,
6637 if (!pMFCreateVideoSampleAllocatorEx)
6639 win_skip("MFCreateVideoSampleAllocatorEx() is not available.\n");
6640 return;
6643 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
6644 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6646 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
6647 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
6648 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
6650 IUnknown_Release(unk);
6652 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6653 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6655 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6656 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6658 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6659 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6661 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
6662 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6664 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6665 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6667 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
6668 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6670 count = 10;
6671 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6672 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6673 ok(!count, "Unexpected count %d.\n", count);
6675 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6676 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6678 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6679 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6681 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
6682 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6684 hr = MFCreateMediaType(&media_type);
6685 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6687 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
6688 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6690 video_type = create_video_type(&MFVideoFormat_RGB32);
6691 video_type2 = create_video_type(&MFVideoFormat_RGB32);
6693 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6694 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6696 /* Frame size is required. */
6697 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6698 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6700 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6701 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6703 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6704 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6706 EXPECT_REF(video_type, 1);
6707 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6708 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6709 EXPECT_REF(video_type, 2);
6711 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
6712 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6714 /* Setting identical type does not replace it. */
6715 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6716 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6717 EXPECT_REF(video_type, 2);
6718 EXPECT_REF(video_type2, 1);
6720 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
6721 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6723 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6724 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6725 EXPECT_REF(video_type2, 2);
6726 EXPECT_REF(video_type, 1);
6728 /* Modify referenced type. */
6729 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
6730 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6732 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6733 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6734 EXPECT_REF(video_type, 2);
6735 EXPECT_REF(video_type2, 1);
6737 count = 0;
6738 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6739 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6740 ok(count == 1, "Unexpected count %d.\n", count);
6742 sample = NULL;
6743 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6744 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6745 refcount = get_refcount(sample);
6747 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6748 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6749 ok(!count, "Unexpected count %d.\n", count);
6751 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
6752 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6754 /* Reinitialize with active sample. */
6755 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6756 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6757 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
6758 EXPECT_REF(video_type, 2);
6760 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6761 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6762 todo_wine
6763 ok(!count, "Unexpected count %d.\n", count);
6765 check_interface(sample, &IID_IMFTrackedSample, TRUE);
6766 check_interface(sample, &IID_IMFDesiredSample, FALSE);
6768 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6769 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6771 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6772 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6773 check_interface(buffer, &IID_IMFGetService, TRUE);
6774 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
6776 IMFMediaBuffer_Release(buffer);
6778 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6779 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6780 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
6782 IMFSample_Release(sample);
6784 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6785 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6786 todo_wine
6787 EXPECT_REF(video_type, 2);
6789 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6790 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6791 ok(!count, "Unexpected count %d.\n", count);
6793 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6794 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6796 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6797 IMFVideoSampleAllocator_Release(allocator);
6799 /* IMFVideoSampleAllocatorEx */
6800 hr = MFCreateAttributes(&attributes, 0);
6801 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6803 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6804 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6806 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6807 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6809 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
6810 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6812 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
6813 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6815 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6816 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6818 EXPECT_REF(attributes, 1);
6819 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6820 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6821 EXPECT_REF(attributes, 2);
6823 count = 0;
6824 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6825 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6826 ok(count == 1, "Unexpected count %d.\n", count);
6828 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6829 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6831 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6832 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6833 ok(buffer_count == 2, "Unexpected buffer count %u.\n", buffer_count);
6835 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6836 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6838 /* Reinitialize with already allocated samples. */
6839 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
6840 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6841 EXPECT_REF(attributes, 1);
6843 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6844 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6845 IMFSample_Release(sample2);
6847 IMFSample_Release(sample);
6849 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6850 IMFVideoSampleAllocatorEx_Release(allocatorex);
6851 IMFAttributes_Release(attributes);
6853 /* Using device manager */
6854 if (!(device = create_d3d11_device()))
6856 skip("Failed to create a D3D11 device, skipping tests.\n");
6857 return;
6860 hr = pMFCreateDXGIDeviceManager(&token, &manager);
6861 ok(hr == S_OK, "Failed to create device manager, hr %#x.\n", hr);
6863 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
6864 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
6866 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6867 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6869 EXPECT_REF(manager, 1);
6870 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
6871 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6872 EXPECT_REF(manager, 2);
6874 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6875 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6877 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6878 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6880 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6881 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6883 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6884 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6886 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6887 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6888 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6889 check_interface(buffer, &IID_IMFGetService, FALSE);
6891 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6892 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6894 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6895 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6897 ID3D11Texture2D_GetDesc(texture, &desc);
6898 ok(desc.Width == 320, "Unexpected width %u.\n", desc.Width);
6899 ok(desc.Height == 240, "Unexpected height %u.\n", desc.Height);
6900 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
6901 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
6902 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
6903 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
6904 ok(desc.SampleDesc.Quality == 0, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
6905 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
6906 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6907 desc.BindFlags);
6908 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6909 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6911 ID3D11Texture2D_Release(texture);
6912 IMFDXGIBuffer_Release(dxgi_buffer);
6914 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6915 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6917 hr = IMFMediaBuffer_Unlock(buffer);
6918 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6920 IMFSample_Release(sample);
6922 IMFVideoSampleAllocator_Release(allocator);
6924 /* MF_SA_D3D11_USAGE */
6925 hr = MFCreateAttributes(&attributes, 1);
6926 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
6928 for (i = 0; i < ARRAY_SIZE(usage); ++i)
6930 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6931 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6933 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
6934 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6936 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
6937 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6939 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6940 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
6942 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6943 IMFVideoSampleAllocatorEx_Release(allocatorex);
6944 continue;
6946 ok(hr == S_OK, "%u: Unexpected hr %#x.\n", usage[i], hr);
6948 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
6949 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6951 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6954 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6955 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6957 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6958 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6960 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6961 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6963 ID3D11Texture2D_GetDesc(texture, &desc);
6964 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
6965 if (usage[i] == D3D11_USAGE_DEFAULT)
6967 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6968 desc.BindFlags);
6969 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6971 else if (usage[i] == D3D11_USAGE_DYNAMIC)
6973 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
6974 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6976 else if (usage[i] == D3D11_USAGE_STAGING)
6978 ok(desc.BindFlags == 0, "Unexpected bind flags %#x.\n", desc.BindFlags);
6979 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
6980 desc.CPUAccessFlags);
6982 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6984 ID3D11Texture2D_Release(texture);
6985 IMFDXGIBuffer_Release(dxgi_buffer);
6986 IMFMediaBuffer_Release(buffer);
6988 IMFSample_Release(sample);
6990 IMFVideoSampleAllocatorEx_Release(allocatorex);
6993 IMFAttributes_Release(attributes);
6995 IMFDXGIDeviceManager_Release(manager);
6996 ID3D11Device_Release(device);
6998 /* Use D3D9 device manager. */
6999 window = create_window();
7000 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
7001 ok(!!d3d9, "Failed to create a D3D9 object.\n");
7002 if (!(d3d9_device = create_device(d3d9, window)))
7004 skip("Failed to create a D3D9 device, skipping tests.\n");
7005 goto done;
7008 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
7009 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7011 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
7012 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7014 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7015 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7017 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
7018 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7020 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7021 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7023 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7024 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7026 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7027 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7029 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7030 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7032 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7033 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7034 check_interface(buffer, &IID_IMFGetService, TRUE);
7035 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7037 IMFSample_Release(sample);
7038 IMFMediaBuffer_Release(buffer);
7040 IMFVideoSampleAllocator_Release(allocator);
7041 IMFMediaType_Release(media_type);
7043 done:
7044 IDirect3D9_Release(d3d9);
7045 DestroyWindow(window);
7048 static void test_MFLockSharedWorkQueue(void)
7050 DWORD taskid, queue, queue2;
7051 HRESULT hr;
7053 if (!pMFLockSharedWorkQueue)
7055 win_skip("MFLockSharedWorkQueue() is not available.\n");
7056 return;
7059 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
7060 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
7062 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
7063 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
7065 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
7066 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
7068 taskid = 0;
7069 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
7070 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7072 queue = 0;
7073 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
7074 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
7076 queue2 = 0;
7077 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
7078 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7079 ok(queue == queue2, "Unexpected queue %#x.\n", queue2);
7081 hr = MFUnlockWorkQueue(queue2);
7082 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7084 hr = MFUnlockWorkQueue(queue);
7085 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7087 hr = MFShutdown();
7088 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
7091 START_TEST(mfplat)
7093 char **argv;
7094 int argc;
7096 init_functions();
7098 argc = winetest_get_mainargs(&argv);
7099 if (argc >= 3)
7101 test_queue_com_state(argv[2]);
7102 return;
7105 CoInitialize(NULL);
7107 test_startup();
7108 test_register();
7109 test_media_type();
7110 test_MFCreateMediaEvent();
7111 test_attributes();
7112 test_sample();
7113 test_file_stream();
7114 test_MFCreateMFByteStreamOnStream();
7115 test_system_memory_buffer();
7116 test_source_resolver();
7117 test_MFCreateAsyncResult();
7118 test_allocate_queue();
7119 test_MFLockSharedWorkQueue();
7120 test_MFCopyImage();
7121 test_MFCreateCollection();
7122 test_MFHeapAlloc();
7123 test_scheduled_items();
7124 test_serial_queue();
7125 test_periodic_callback();
7126 test_event_queue();
7127 test_presentation_descriptor();
7128 test_system_time_source();
7129 test_MFInvokeCallback();
7130 test_stream_descriptor();
7131 test_MFCalculateImageSize();
7132 test_MFCompareFullToPartialMediaType();
7133 test_attributes_serialization();
7134 test_wrapped_media_type();
7135 test_MFCreateWaveFormatExFromMFMediaType();
7136 test_async_create_file();
7137 test_local_handlers();
7138 test_create_property_store();
7139 test_dxgi_device_manager();
7140 test_MFCreateTransformActivate();
7141 test_MFTRegisterLocal();
7142 test_queue_com();
7143 test_MFGetStrideForBitmapInfoHeader();
7144 test_MFCreate2DMediaBuffer();
7145 test_MFCreateMediaBufferFromMediaType();
7146 test_MFInitMediaTypeFromWaveFormatEx();
7147 test_MFCreateMFVideoFormatFromMFMediaType();
7148 test_MFCreateDXSurfaceBuffer();
7149 test_MFCreateTrackedSample();
7150 test_MFFrameRateToAverageTimePerFrame();
7151 test_MFMapDXGIFormatToDX9Format();
7152 test_dxgi_surface_buffer();
7153 test_sample_allocator();
7154 test_MFMapDX9FormatToDXGIFormat();
7156 CoUninitialize();