winegstreamer: Implement a stub IMFRateSupport for the media source.
[wine.git] / dlls / mfplat / tests / mfplat.c
bloba38cecab82783d84b1dd8ea9ce984aef3a22c5a4
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 todo_wine
763 check_service_interface(mediasource, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
764 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, &descriptor);
765 ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
766 ok(descriptor != NULL, "got %p\n", descriptor);
768 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
769 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
771 hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler);
772 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
773 IMFStreamDescriptor_Release(sd);
775 hr = IMFMediaTypeHandler_GetMajorType(handler, &guid);
776 ok(hr == S_OK, "Failed to get stream major type, hr %#x.\n", hr);
778 /* Check major/minor type for the test media. */
779 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type %s.\n", debugstr_guid(&guid));
781 hr = IMFMediaTypeHandler_GetCurrentMediaType(handler, &media_type);
782 ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
783 hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
784 ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
785 todo_wine
786 ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
787 IMFMediaType_Release(media_type);
789 hr = IMFPresentationDescriptor_SelectStream(descriptor, 0);
790 ok(hr == S_OK, "Failed to select video stream, hr %#x.\n", hr);
792 var.vt = VT_EMPTY;
793 hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
794 ok(hr == S_OK, "Failed to start media source, hr %#x.\n", hr);
796 video_stream = NULL;
797 if (get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var))
799 ok(var.vt == VT_UNKNOWN, "Unexpected value type.\n");
800 video_stream = (IMFMediaStream *)var.punkVal;
803 sample_count = 10;
805 for (i = 0; i < sample_count; ++i)
807 hr = IMFMediaStream_RequestSample(video_stream, NULL);
808 if (i == sample_count)
809 break;
810 ok(hr == S_OK, "Failed to request sample %u, hr %#x.\n", i + 1, hr);
811 if (hr != S_OK)
812 break;
815 for (i = 0; i < sample_count; ++i)
817 static const LONGLONG MILLI_TO_100_NANO = 10000;
818 LONGLONG duration, time;
819 DWORD buffer_count;
820 IMFSample *sample;
821 BOOL ret;
823 ret = get_event((IMFMediaEventGenerator *)video_stream, MEMediaSample, &var);
824 ok(ret, "Sample %u not received.\n", i + 1);
825 if (!ret)
826 break;
828 ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MEMediaSample event.\n", var.vt);
829 sample = (IMFSample *)var.punkVal;
831 hr = IMFSample_GetBufferCount(sample, &buffer_count);
832 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
833 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
835 hr = IMFSample_GetSampleDuration(sample, &duration);
836 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
837 ok(duration == 40 * MILLI_TO_100_NANO, "Unexpected duration %s.\n", wine_dbgstr_longlong(duration));
839 hr = IMFSample_GetSampleTime(sample, &time);
840 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
841 ok(time == i * 40 * MILLI_TO_100_NANO, "Unexpected time %s.\n", wine_dbgstr_longlong(time));
843 IMFSample_Release(sample);
846 if (i == sample_count)
848 IMFMediaEvent *event;
850 /* MEEndOfStream isn't queued until after a one request beyond the last frame is submitted */
851 Sleep(100);
852 hr = IMFMediaEventGenerator_GetEvent((IMFMediaEventGenerator *)video_stream, MF_EVENT_FLAG_NO_WAIT, &event);
853 ok (hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
855 hr = IMFMediaStream_RequestSample(video_stream, NULL);
856 ok (hr == S_OK || hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
857 get_event((IMFMediaEventGenerator *)video_stream, MEEndOfStream, NULL);
861 hr = IMFMediaStream_RequestSample(video_stream, NULL);
862 ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
864 get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
866 IMFMediaStream_Release(video_stream);
867 IMFMediaTypeHandler_Release(handler);
868 IMFPresentationDescriptor_Release(descriptor);
870 hr = IMFMediaSource_Shutdown(mediasource);
871 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
873 hr = IMFMediaSource_CreatePresentationDescriptor(mediasource, NULL);
874 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
876 IMFMediaSource_Release(mediasource);
877 IMFByteStream_Release(stream);
879 /* Create directly through scheme handler. */
880 hr = CoInitialize(NULL);
881 ok(SUCCEEDED(hr), "Failed to initialize, hr %#x.\n", hr);
882 do_uninit = hr == S_OK;
884 hr = CoCreateInstance(&CLSID_FileSchemePlugin, NULL, CLSCTX_INPROC_SERVER, &IID_IMFSchemeHandler,
885 (void **)&scheme_handler);
886 ok(hr == S_OK, "Failed to create handler object, hr %#x.\n", hr);
888 callback2.event = callback.event;
889 cancel_cookie = NULL;
890 hr = IMFSchemeHandler_BeginCreateObject(scheme_handler, pathW, MF_RESOLUTION_MEDIASOURCE, NULL, &cancel_cookie,
891 &callback2.IMFAsyncCallback_iface, (IUnknown *)scheme_handler);
892 ok(hr == S_OK, "Create request failed, hr %#x.\n", hr);
893 ok(!!cancel_cookie, "Unexpected cancel object.\n");
894 IUnknown_Release(cancel_cookie);
896 WaitForSingleObject(callback2.event, INFINITE);
898 IMFSchemeHandler_Release(scheme_handler);
900 if (do_uninit)
901 CoUninitialize();
903 CloseHandle(callback.event);
905 IMFSourceResolver_Release(resolver);
907 hr = MFShutdown();
908 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
910 DeleteFileW(filename);
913 static void init_functions(void)
915 HMODULE mod = GetModuleHandleA("mfplat.dll");
917 #define X(f) p##f = (void*)GetProcAddress(mod, #f)
918 X(MFAddPeriodicCallback);
919 X(MFAllocateSerialWorkQueue);
920 X(MFAllocateWorkQueueEx);
921 X(MFCopyImage);
922 X(MFCreate2DMediaBuffer);
923 X(MFCreateDXGIDeviceManager);
924 X(MFCreateDXGISurfaceBuffer);
925 X(MFCreateDXSurfaceBuffer);
926 X(MFCreateSourceResolver);
927 X(MFCreateMediaBufferFromMediaType);
928 X(MFCreateMFByteStreamOnStream);
929 X(MFCreateTrackedSample);
930 X(MFCreateTransformActivate);
931 X(MFCreateVideoMediaTypeFromSubtype);
932 X(MFCreateVideoSampleAllocatorEx);
933 X(MFGetPlaneSize);
934 X(MFGetStrideForBitmapInfoHeader);
935 X(MFLockSharedWorkQueue);
936 X(MFMapDX9FormatToDXGIFormat);
937 X(MFMapDXGIFormatToDX9Format);
938 X(MFPutWaitingWorkItem);
939 X(MFRegisterLocalByteStreamHandler);
940 X(MFRegisterLocalSchemeHandler);
941 X(MFRemovePeriodicCallback);
942 X(MFTEnumEx);
943 X(MFTRegisterLocal);
944 X(MFTRegisterLocalByCLSID);
945 X(MFTUnregisterLocal);
946 X(MFTUnregisterLocalByCLSID);
948 if ((mod = LoadLibraryA("d3d11.dll")))
950 X(D3D11CreateDevice);
953 mod = GetModuleHandleA("ole32.dll");
955 X(CoGetApartmentType);
956 #undef X
958 is_win8_plus = pMFPutWaitingWorkItem != NULL;
961 static void test_media_type(void)
963 IMFMediaType *mediatype, *mediatype2;
964 IMFVideoMediaType *video_type;
965 IUnknown *unk, *unk2;
966 DWORD count, flags;
967 BOOL compressed;
968 HRESULT hr;
969 GUID guid;
971 if(0)
973 /* Crash on Windows Vista/7 */
974 hr = MFCreateMediaType(NULL);
975 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
978 hr = MFCreateMediaType(&mediatype);
979 ok(hr == S_OK, "got 0x%08x\n", hr);
981 hr = IMFMediaType_GetMajorType(mediatype, &guid);
982 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
984 compressed = FALSE;
985 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
986 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
987 ok(compressed, "Unexpected value %d.\n", compressed);
989 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 0);
990 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
992 compressed = FALSE;
993 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
994 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
995 ok(compressed, "Unexpected value %d.\n", compressed);
997 hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1);
998 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1000 compressed = TRUE;
1001 hr = IMFMediaType_IsCompressedFormat(mediatype, &compressed);
1002 ok(hr == S_OK, "Failed to get media type property, hr %#x.\n", hr);
1003 ok(!compressed, "Unexpected value %d.\n", compressed);
1005 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1006 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1008 hr = IMFMediaType_GetMajorType(mediatype, &guid);
1009 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
1010 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
1012 /* IsEqual() */
1013 hr = MFCreateMediaType(&mediatype2);
1014 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
1016 flags = 0xdeadbeef;
1017 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1018 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1019 ok(flags == 0, "Unexpected flags %#x.\n", flags);
1021 /* Different major types. */
1022 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1023 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
1025 flags = 0;
1026 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1027 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1028 ok(flags == (MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1029 "Unexpected flags %#x.\n", flags);
1031 /* Same major types, different subtypes. */
1032 hr = IMFMediaType_SetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1033 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
1035 flags = 0;
1036 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1037 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1038 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA
1039 | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA), "Unexpected flags %#x.\n", flags);
1041 /* Different user data. */
1042 hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)&flags, sizeof(flags));
1043 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
1045 flags = 0;
1046 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1047 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1048 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA),
1049 "Unexpected flags %#x.\n", flags);
1051 hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA);
1052 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1054 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
1055 ok(hr == S_OK, "Failed to set subtype, hr %#x.\n", hr);
1057 flags = 0;
1058 hr = IMFMediaType_IsEqual(mediatype, mediatype2, &flags);
1059 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
1060 ok(flags == (MF_MEDIATYPE_EQUAL_MAJOR_TYPES | MF_MEDIATYPE_EQUAL_FORMAT_DATA | MF_MEDIATYPE_EQUAL_FORMAT_USER_DATA),
1061 "Unexpected flags %#x.\n", flags);
1063 IMFMediaType_Release(mediatype2);
1064 IMFMediaType_Release(mediatype);
1066 /* IMFVideoMediaType */
1067 hr = MFCreateMediaType(&mediatype);
1068 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1070 check_interface(mediatype, &IID_IMFVideoMediaType, FALSE);
1072 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1073 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1074 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1075 IUnknown_Release(unk);
1077 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
1078 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1080 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFVideoMediaType, (void **)&unk);
1081 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1083 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1084 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1085 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1086 IUnknown_Release(unk2);
1088 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1089 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1090 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1091 IUnknown_Release(unk2);
1093 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1094 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1095 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1096 IUnknown_Release(unk2);
1098 IUnknown_Release(unk);
1099 IMFMediaType_Release(mediatype);
1101 if (pMFCreateVideoMediaTypeFromSubtype)
1103 hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB555, &video_type);
1104 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1106 check_interface(video_type, &IID_IMFMediaType, TRUE);
1107 check_interface(video_type, &IID_IMFVideoMediaType, TRUE);
1109 /* Major and subtype are set on creation. */
1110 hr = IMFVideoMediaType_GetCount(video_type, &count);
1111 ok(count == 2, "Unexpected attribute count %#x.\n", hr);
1113 hr = IMFVideoMediaType_DeleteAllItems(video_type);
1114 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1116 hr = IMFVideoMediaType_GetCount(video_type, &count);
1117 ok(!count, "Unexpected attribute count %#x.\n", hr);
1119 check_interface(video_type, &IID_IMFVideoMediaType, FALSE);
1121 IMFVideoMediaType_Release(video_type);
1123 else
1124 win_skip("MFCreateVideoMediaTypeFromSubtype() is not available.\n");
1126 /* IMFAudioMediaType */
1127 hr = MFCreateMediaType(&mediatype);
1128 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1130 check_interface(mediatype, &IID_IMFAudioMediaType, FALSE);
1132 hr = IMFMediaType_QueryInterface(mediatype, &IID_IUnknown, (void **)&unk);
1133 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1134 ok(unk == (IUnknown *)mediatype, "Unexpected pointer.\n");
1135 IUnknown_Release(unk);
1137 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
1138 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
1140 hr = IMFMediaType_QueryInterface(mediatype, &IID_IMFAudioMediaType, (void **)&unk);
1141 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1143 hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2);
1144 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1145 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1146 IUnknown_Release(unk2);
1148 hr = IUnknown_QueryInterface(unk, &IID_IMFAttributes, (void **)&unk2);
1149 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1150 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1151 IUnknown_Release(unk2);
1153 hr = IUnknown_QueryInterface(unk, &IID_IMFMediaType, (void **)&unk2);
1154 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1155 ok(unk2 == (IUnknown *)mediatype, "Unexpected pointer.\n");
1156 IUnknown_Release(unk2);
1158 IUnknown_Release(unk);
1160 IMFMediaType_Release(mediatype);
1163 static void test_MFCreateMediaEvent(void)
1165 HRESULT hr;
1166 IMFMediaEvent *mediaevent;
1168 MediaEventType type;
1169 GUID extended_type;
1170 HRESULT status;
1171 PROPVARIANT value;
1173 PropVariantInit(&value);
1174 value.vt = VT_UNKNOWN;
1176 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, &value, &mediaevent);
1177 ok(hr == S_OK, "got 0x%08x\n", hr);
1179 PropVariantClear(&value);
1181 hr = IMFMediaEvent_GetType(mediaevent, &type);
1182 ok(hr == S_OK, "got 0x%08x\n", hr);
1183 ok(type == MEError, "got %#x\n", type);
1185 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1186 ok(hr == S_OK, "got 0x%08x\n", hr);
1187 ok(IsEqualGUID(&extended_type, &GUID_NULL), "got %s\n",
1188 wine_dbgstr_guid(&extended_type));
1190 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1191 ok(hr == S_OK, "got 0x%08x\n", hr);
1192 ok(status == E_FAIL, "got 0x%08x\n", status);
1194 PropVariantInit(&value);
1195 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1196 ok(hr == S_OK, "got 0x%08x\n", hr);
1197 ok(value.vt == VT_UNKNOWN, "got %#x\n", value.vt);
1198 PropVariantClear(&value);
1200 IMFMediaEvent_Release(mediaevent);
1202 hr = MFCreateMediaEvent(MEUnknown, &DUMMY_GUID1, S_OK, NULL, &mediaevent);
1203 ok(hr == S_OK, "got 0x%08x\n", hr);
1205 hr = IMFMediaEvent_GetType(mediaevent, &type);
1206 ok(hr == S_OK, "got 0x%08x\n", hr);
1207 ok(type == MEUnknown, "got %#x\n", type);
1209 hr = IMFMediaEvent_GetExtendedType(mediaevent, &extended_type);
1210 ok(hr == S_OK, "got 0x%08x\n", hr);
1211 ok(IsEqualGUID(&extended_type, &DUMMY_GUID1), "got %s\n",
1212 wine_dbgstr_guid(&extended_type));
1214 hr = IMFMediaEvent_GetStatus(mediaevent, &status);
1215 ok(hr == S_OK, "got 0x%08x\n", hr);
1216 ok(status == S_OK, "got 0x%08x\n", status);
1218 PropVariantInit(&value);
1219 hr = IMFMediaEvent_GetValue(mediaevent, &value);
1220 ok(hr == S_OK, "got 0x%08x\n", hr);
1221 ok(value.vt == VT_EMPTY, "got %#x\n", value.vt);
1222 PropVariantClear(&value);
1224 IMFMediaEvent_Release(mediaevent);
1227 #define CHECK_ATTR_COUNT(obj, expected) check_attr_count(obj, expected, __LINE__)
1228 static void check_attr_count(IMFAttributes* obj, UINT32 expected, int line)
1230 UINT32 count = expected + 1;
1231 HRESULT hr = IMFAttributes_GetCount(obj, &count);
1232 ok_(__FILE__, line)(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1233 ok_(__FILE__, line)(count == expected, "Unexpected count %u, expected %u.\n", count, expected);
1236 #define CHECK_ATTR_TYPE(obj, key, expected) check_attr_type(obj, key, expected, __LINE__)
1237 static void check_attr_type(IMFAttributes *obj, const GUID *key, MF_ATTRIBUTE_TYPE expected, int line)
1239 MF_ATTRIBUTE_TYPE type;
1240 HRESULT hr;
1242 hr = IMFAttributes_GetItemType(obj, key, &type);
1243 ok_(__FILE__, line)(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1244 ok_(__FILE__, line)(type == expected, "Unexpected item type %d, expected %d.\n", type, expected);
1247 static void test_attributes(void)
1249 static const WCHAR stringW[] = L"Wine";
1250 static const UINT8 blob[] = {0,1,2,3,4,5};
1251 IMFAttributes *attributes, *attributes1;
1252 UINT8 blob_value[256], *blob_buf = NULL;
1253 MF_ATTRIBUTES_MATCH_TYPE match_type;
1254 UINT32 value, string_length, size;
1255 PROPVARIANT propvar, ret_propvar;
1256 MF_ATTRIBUTE_TYPE type;
1257 double double_value;
1258 IUnknown *unk_value;
1259 WCHAR bufferW[256];
1260 UINT64 value64;
1261 WCHAR *string;
1262 BOOL result;
1263 HRESULT hr;
1264 GUID key;
1266 hr = MFCreateAttributes( &attributes, 3 );
1267 ok(hr == S_OK, "got 0x%08x\n", hr);
1269 hr = IMFAttributes_GetItemType(attributes, &GUID_NULL, &type);
1270 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1272 CHECK_ATTR_COUNT(attributes, 0);
1273 hr = IMFAttributes_SetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 123);
1274 ok(hr == S_OK, "Failed to set UINT32 value, hr %#x.\n", hr);
1275 CHECK_ATTR_COUNT(attributes, 1);
1276 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT32);
1278 value = 0xdeadbeef;
1279 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1280 ok(hr == S_OK, "Failed to get UINT32 value, hr %#x.\n", hr);
1281 ok(value == 123, "Unexpected value %u, expected: 123.\n", value);
1283 value64 = 0xdeadbeef;
1284 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1285 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1286 ok(value64 == 0xdeadbeef, "Unexpected value.\n");
1288 hr = IMFAttributes_SetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 65536);
1289 ok(hr == S_OK, "Failed to set UINT64 value, hr %#x.\n", hr);
1290 CHECK_ATTR_COUNT(attributes, 1);
1291 CHECK_ATTR_TYPE(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, MF_ATTRIBUTE_UINT64);
1293 hr = IMFAttributes_GetUINT64(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value64);
1294 ok(hr == S_OK, "Failed to get UINT64 value, hr %#x.\n", hr);
1295 ok(value64 == 65536, "Unexpected value.\n");
1297 value = 0xdeadbeef;
1298 hr = IMFAttributes_GetUINT32(attributes, &MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, &value);
1299 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1300 ok(value == 0xdeadbeef, "Unexpected value.\n");
1302 IMFAttributes_Release(attributes);
1304 hr = MFCreateAttributes(&attributes, 0);
1305 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1307 PropVariantInit(&propvar);
1308 propvar.vt = MF_ATTRIBUTE_UINT32;
1309 U(propvar).ulVal = 123;
1310 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1311 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1312 PropVariantInit(&ret_propvar);
1313 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1314 U(ret_propvar).ulVal = 0xdeadbeef;
1315 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1316 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1317 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1318 PropVariantClear(&ret_propvar);
1319 CHECK_ATTR_COUNT(attributes, 1);
1321 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, NULL);
1322 ok(hr == S_OK, "Item check failed, hr %#x.\n", hr);
1324 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, NULL);
1325 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1327 PropVariantInit(&ret_propvar);
1328 ret_propvar.vt = MF_ATTRIBUTE_STRING;
1329 U(ret_propvar).pwszVal = NULL;
1330 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1331 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1332 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1333 PropVariantClear(&ret_propvar);
1335 PropVariantClear(&propvar);
1337 PropVariantInit(&propvar);
1338 propvar.vt = MF_ATTRIBUTE_UINT64;
1339 U(propvar).uhVal.QuadPart = 65536;
1340 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID1, &propvar);
1341 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1342 PropVariantInit(&ret_propvar);
1343 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1344 U(ret_propvar).ulVal = 0xdeadbeef;
1345 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1346 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1347 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1348 PropVariantClear(&ret_propvar);
1349 PropVariantClear(&propvar);
1350 CHECK_ATTR_COUNT(attributes, 1);
1352 PropVariantInit(&propvar);
1353 propvar.vt = VT_I4;
1354 U(propvar).lVal = 123;
1355 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID2, &propvar);
1356 ok(hr == MF_E_INVALIDTYPE, "Failed to set item, hr %#x.\n", hr);
1357 PropVariantInit(&ret_propvar);
1358 ret_propvar.vt = MF_ATTRIBUTE_UINT32;
1359 U(ret_propvar).lVal = 0xdeadbeef;
1360 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID2, &ret_propvar);
1361 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1362 PropVariantClear(&propvar);
1363 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1364 PropVariantClear(&ret_propvar);
1366 PropVariantInit(&propvar);
1367 propvar.vt = MF_ATTRIBUTE_UINT32;
1368 U(propvar).ulVal = 123;
1369 hr = IMFAttributes_SetItem(attributes, &DUMMY_GUID3, &propvar);
1370 ok(hr == S_OK, "Failed to set item, hr %#x.\n", hr);
1372 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1373 ok(hr == S_OK, "Failed to delete item, hr %#x.\n", hr);
1374 CHECK_ATTR_COUNT(attributes, 2);
1376 hr = IMFAttributes_DeleteItem(attributes, &DUMMY_GUID2);
1377 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1378 CHECK_ATTR_COUNT(attributes, 2);
1380 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID3, &ret_propvar);
1381 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1382 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1383 PropVariantClear(&ret_propvar);
1384 PropVariantClear(&propvar);
1386 propvar.vt = MF_ATTRIBUTE_UINT64;
1387 U(propvar).uhVal.QuadPart = 65536;
1389 hr = IMFAttributes_GetItem(attributes, &DUMMY_GUID1, &ret_propvar);
1390 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1391 ok(!PropVariantCompareEx(&propvar, &ret_propvar, 0, 0), "Unexpected item value.\n");
1392 PropVariantClear(&ret_propvar);
1393 PropVariantClear(&propvar);
1395 /* Item ordering is not consistent across Windows version. */
1396 hr = IMFAttributes_GetItemByIndex(attributes, 0, &key, &ret_propvar);
1397 ok(hr == S_OK, "Failed to get item, hr %#x.\n", hr);
1398 PropVariantClear(&ret_propvar);
1400 hr = IMFAttributes_GetItemByIndex(attributes, 100, &key, &ret_propvar);
1401 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1402 PropVariantClear(&ret_propvar);
1404 hr = IMFAttributes_SetDouble(attributes, &GUID_NULL, 22.0);
1405 ok(hr == S_OK, "Failed to set double value, hr %#x.\n", hr);
1406 CHECK_ATTR_COUNT(attributes, 3);
1407 CHECK_ATTR_TYPE(attributes, &GUID_NULL, MF_ATTRIBUTE_DOUBLE);
1409 double_value = 0xdeadbeef;
1410 hr = IMFAttributes_GetDouble(attributes, &GUID_NULL, &double_value);
1411 ok(hr == S_OK, "Failed to get double value, hr %#x.\n", hr);
1412 ok(double_value == 22.0, "Unexpected value: %f, expected: 22.0.\n", double_value);
1414 propvar.vt = MF_ATTRIBUTE_UINT64;
1415 U(propvar).uhVal.QuadPart = 22;
1416 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1417 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1418 ok(!result, "Unexpected result.\n");
1420 propvar.vt = MF_ATTRIBUTE_DOUBLE;
1421 U(propvar).dblVal = 22.0;
1422 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1423 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1424 ok(result, "Unexpected result.\n");
1426 hr = IMFAttributes_SetString(attributes, &DUMMY_GUID1, stringW);
1427 ok(hr == S_OK, "Failed to set string attribute, hr %#x.\n", hr);
1428 CHECK_ATTR_COUNT(attributes, 3);
1429 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_STRING);
1431 hr = IMFAttributes_GetStringLength(attributes, &DUMMY_GUID1, &string_length);
1432 ok(hr == S_OK, "Failed to get string length, hr %#x.\n", hr);
1433 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1435 string_length = 0xdeadbeef;
1436 hr = IMFAttributes_GetAllocatedString(attributes, &DUMMY_GUID1, &string, &string_length);
1437 ok(hr == S_OK, "Failed to get allocated string, hr %#x.\n", hr);
1438 ok(!lstrcmpW(string, stringW), "Unexpected string %s.\n", wine_dbgstr_w(string));
1439 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1440 CoTaskMemFree(string);
1442 string_length = 0xdeadbeef;
1443 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), &string_length);
1444 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1445 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1446 ok(string_length == lstrlenW(stringW), "Unexpected length %u.\n", string_length);
1447 memset(bufferW, 0, sizeof(bufferW));
1449 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, ARRAY_SIZE(bufferW), NULL);
1450 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
1451 ok(!lstrcmpW(bufferW, stringW), "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1452 memset(bufferW, 0, sizeof(bufferW));
1454 string_length = 0;
1455 hr = IMFAttributes_GetString(attributes, &DUMMY_GUID1, bufferW, 1, &string_length);
1456 ok(hr == STRSAFE_E_INSUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1457 ok(!bufferW[0], "Unexpected string %s.\n", wine_dbgstr_w(bufferW));
1458 ok(string_length, "Unexpected length.\n");
1460 string_length = 0xdeadbeef;
1461 hr = IMFAttributes_GetStringLength(attributes, &GUID_NULL, &string_length);
1462 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1463 ok(string_length == 0xdeadbeef, "Unexpected length %u.\n", string_length);
1465 /* VT_UNKNOWN */
1466 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_GUID2, (IUnknown *)attributes);
1467 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1468 CHECK_ATTR_COUNT(attributes, 4);
1469 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID2, MF_ATTRIBUTE_IUNKNOWN);
1471 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IUnknown, (void **)&unk_value);
1472 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1473 IUnknown_Release(unk_value);
1475 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IMFAttributes, (void **)&unk_value);
1476 ok(hr == S_OK, "Failed to get value, hr %#x.\n", hr);
1477 IUnknown_Release(unk_value);
1479 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_GUID2, &IID_IStream, (void **)&unk_value);
1480 ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
1482 hr = IMFAttributes_SetUnknown(attributes, &DUMMY_CLSID, NULL);
1483 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1484 CHECK_ATTR_COUNT(attributes, 5);
1486 unk_value = NULL;
1487 hr = IMFAttributes_GetUnknown(attributes, &DUMMY_CLSID, &IID_IUnknown, (void **)&unk_value);
1488 ok(hr == MF_E_INVALIDTYPE, "Unexpected hr %#x.\n", hr);
1490 /* CopyAllItems() */
1491 hr = MFCreateAttributes(&attributes1, 0);
1492 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1493 hr = IMFAttributes_CopyAllItems(attributes, attributes1);
1494 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1495 CHECK_ATTR_COUNT(attributes, 5);
1496 CHECK_ATTR_COUNT(attributes1, 5);
1498 hr = IMFAttributes_DeleteAllItems(attributes1);
1499 ok(hr == S_OK, "Failed to delete items, hr %#x.\n", hr);
1500 CHECK_ATTR_COUNT(attributes1, 0);
1502 propvar.vt = MF_ATTRIBUTE_UINT64;
1503 U(propvar).uhVal.QuadPart = 22;
1504 hr = IMFAttributes_CompareItem(attributes, &GUID_NULL, &propvar, &result);
1505 ok(hr == S_OK, "Failed to compare items, hr %#x.\n", hr);
1506 ok(!result, "Unexpected result.\n");
1508 hr = IMFAttributes_CopyAllItems(attributes1, attributes);
1509 ok(hr == S_OK, "Failed to copy items, hr %#x.\n", hr);
1510 CHECK_ATTR_COUNT(attributes, 0);
1512 /* Blob */
1513 hr = IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
1514 ok(hr == S_OK, "Failed to set blob attribute, hr %#x.\n", hr);
1515 CHECK_ATTR_COUNT(attributes, 1);
1516 CHECK_ATTR_TYPE(attributes, &DUMMY_GUID1, MF_ATTRIBUTE_BLOB);
1517 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID1, &size);
1518 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
1519 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1521 hr = IMFAttributes_GetBlobSize(attributes, &DUMMY_GUID2, &size);
1522 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1524 size = 0;
1525 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob_value), &size);
1526 ok(hr == S_OK, "Failed to get blob, hr %#x.\n", hr);
1527 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1528 ok(!memcmp(blob_value, blob, size), "Unexpected blob.\n");
1530 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID2, blob_value, sizeof(blob_value), &size);
1531 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1533 memset(blob_value, 0, sizeof(blob_value));
1534 size = 0;
1535 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID1, &blob_buf, &size);
1536 ok(hr == S_OK, "Failed to get allocated blob, hr %#x.\n", hr);
1537 ok(size == sizeof(blob), "Unexpected blob size %u.\n", size);
1538 ok(!memcmp(blob_buf, blob, size), "Unexpected blob.\n");
1539 CoTaskMemFree(blob_buf);
1541 hr = IMFAttributes_GetAllocatedBlob(attributes, &DUMMY_GUID2, &blob_buf, &size);
1542 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
1544 hr = IMFAttributes_GetBlob(attributes, &DUMMY_GUID1, blob_value, sizeof(blob) - 1, NULL);
1545 ok(hr == E_NOT_SUFFICIENT_BUFFER, "Unexpected hr %#x.\n", hr);
1547 IMFAttributes_Release(attributes);
1548 IMFAttributes_Release(attributes1);
1550 /* Compare() */
1551 hr = MFCreateAttributes(&attributes, 0);
1552 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1553 hr = MFCreateAttributes(&attributes1, 0);
1554 ok(hr == S_OK, "Failed to create attributes object, hr %#x.\n", hr);
1556 hr = IMFAttributes_Compare(attributes, attributes, MF_ATTRIBUTES_MATCH_SMALLER + 1, &result);
1557 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1559 for (match_type = MF_ATTRIBUTES_MATCH_OUR_ITEMS; match_type <= MF_ATTRIBUTES_MATCH_SMALLER; ++match_type)
1561 result = FALSE;
1562 hr = IMFAttributes_Compare(attributes, attributes, match_type, &result);
1563 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1564 ok(result, "Unexpected result %d.\n", result);
1566 result = FALSE;
1567 hr = IMFAttributes_Compare(attributes, attributes1, match_type, &result);
1568 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1569 ok(result, "Unexpected result %d.\n", result);
1572 hr = IMFAttributes_SetUINT32(attributes, &DUMMY_GUID1, 1);
1573 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1575 result = TRUE;
1576 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1577 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1578 ok(!result, "Unexpected result %d.\n", result);
1580 result = TRUE;
1581 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1582 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1583 ok(!result, "Unexpected result %d.\n", result);
1585 result = FALSE;
1586 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1587 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1588 ok(result, "Unexpected result %d.\n", result);
1590 result = FALSE;
1591 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1592 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1593 ok(result, "Unexpected result %d.\n", result);
1595 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 2);
1596 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1598 result = TRUE;
1599 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1600 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1601 ok(!result, "Unexpected result %d.\n", result);
1603 result = TRUE;
1604 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1605 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1606 ok(!result, "Unexpected result %d.\n", result);
1608 result = TRUE;
1609 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1610 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1611 ok(!result, "Unexpected result %d.\n", result);
1613 result = TRUE;
1614 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1615 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1616 ok(!result, "Unexpected result %d.\n", result);
1618 result = TRUE;
1619 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1620 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1621 ok(!result, "Unexpected result %d.\n", result);
1623 result = TRUE;
1624 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1625 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1626 ok(!result, "Unexpected result %d.\n", result);
1628 result = TRUE;
1629 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1630 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1631 ok(!result, "Unexpected result %d.\n", result);
1633 result = TRUE;
1634 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1635 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1636 ok(!result, "Unexpected result %d.\n", result);
1638 result = TRUE;
1639 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1640 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1641 ok(!result, "Unexpected result %d.\n", result);
1643 result = TRUE;
1644 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1645 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1646 ok(!result, "Unexpected result %d.\n", result);
1648 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID1, 1);
1649 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1651 result = FALSE;
1652 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1653 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1654 ok(result, "Unexpected result %d.\n", result);
1656 result = FALSE;
1657 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1658 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1659 ok(result, "Unexpected result %d.\n", result);
1661 result = FALSE;
1662 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1663 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1664 ok(result, "Unexpected result %d.\n", result);
1666 result = FALSE;
1667 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1668 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1669 ok(result, "Unexpected result %d.\n", result);
1671 result = FALSE;
1672 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1673 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1674 ok(result, "Unexpected result %d.\n", result);
1676 result = FALSE;
1677 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1678 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1679 ok(result, "Unexpected result %d.\n", result);
1681 result = FALSE;
1682 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1683 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1684 ok(result, "Unexpected result %d.\n", result);
1686 result = FALSE;
1687 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1688 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1689 ok(result, "Unexpected result %d.\n", result);
1691 hr = IMFAttributes_SetUINT32(attributes1, &DUMMY_GUID2, 2);
1692 ok(hr == S_OK, "Failed to set value, hr %#x.\n", hr);
1694 result = TRUE;
1695 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1696 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1697 ok(!result, "Unexpected result %d.\n", result);
1699 result = TRUE;
1700 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1701 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1702 ok(!result, "Unexpected result %d.\n", result);
1704 result = FALSE;
1705 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1706 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1707 ok(result, "Unexpected result %d.\n", result);
1709 result = FALSE;
1710 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1711 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1712 ok(result, "Unexpected result %d.\n", result);
1714 result = FALSE;
1715 hr = IMFAttributes_Compare(attributes, attributes1, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1716 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1717 ok(result, "Unexpected result %d.\n", result);
1719 result = TRUE;
1720 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &result);
1721 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1722 ok(!result, "Unexpected result %d.\n", result);
1724 result = FALSE;
1725 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &result);
1726 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1727 ok(result, "Unexpected result %d.\n", result);
1729 result = TRUE;
1730 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &result);
1731 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1732 ok(!result, "Unexpected result %d.\n", result);
1734 result = FALSE;
1735 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_INTERSECTION, &result);
1736 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1737 ok(result, "Unexpected result %d.\n", result);
1739 result = FALSE;
1740 hr = IMFAttributes_Compare(attributes1, attributes, MF_ATTRIBUTES_MATCH_SMALLER, &result);
1741 ok(hr == S_OK, "Failed to compare, hr %#x.\n", hr);
1742 ok(result, "Unexpected result %d.\n", result);
1744 IMFAttributes_Release(attributes);
1745 IMFAttributes_Release(attributes1);
1748 static void test_MFCreateMFByteStreamOnStream(void)
1750 IMFByteStream *bytestream;
1751 IMFByteStream *bytestream2;
1752 IStream *stream;
1753 IMFAttributes *attributes = NULL;
1754 DWORD caps, written, count;
1755 IUnknown *unknown;
1756 ULONG ref, size;
1757 HRESULT hr;
1759 if(!pMFCreateMFByteStreamOnStream)
1761 win_skip("MFCreateMFByteStreamOnStream() not found\n");
1762 return;
1765 hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
1766 ok(hr == S_OK, "got 0x%08x\n", hr);
1768 caps = 0xffff0000;
1769 hr = IStream_Write(stream, &caps, sizeof(caps), &written);
1770 ok(hr == S_OK, "Failed to write, hr %#x.\n", hr);
1772 hr = pMFCreateMFByteStreamOnStream(stream, &bytestream);
1773 ok(hr == S_OK, "got 0x%08x\n", hr);
1775 hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown,
1776 (void **)&unknown);
1777 ok(hr == S_OK, "got 0x%08x\n", hr);
1778 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1779 ref = IUnknown_Release(unknown);
1780 ok(ref == 1, "got %u\n", ref);
1782 hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream,
1783 (void **)&bytestream2);
1784 ok(hr == S_OK, "got 0x%08x\n", hr);
1785 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1786 ref = IMFByteStream_Release(bytestream2);
1787 ok(ref == 1, "got %u\n", ref);
1789 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1790 (void **)&attributes);
1791 ok(hr == S_OK ||
1792 /* w7pro64 */
1793 broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr);
1795 if (hr != S_OK)
1797 win_skip("Cannot retrieve IMFAttributes interface from IMFByteStream\n");
1798 IStream_Release(stream);
1799 IMFByteStream_Release(bytestream);
1800 return;
1803 ok(attributes != NULL, "got NULL\n");
1804 hr = IMFAttributes_GetCount(attributes, &count);
1805 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1806 ok(count == 0, "Unexpected attributes count %u.\n", count);
1808 hr = IMFAttributes_QueryInterface(attributes, &IID_IUnknown,
1809 (void **)&unknown);
1810 ok(hr == S_OK, "got 0x%08x\n", hr);
1811 ok((void *)unknown == (void *)bytestream, "got %p\n", unknown);
1812 ref = IUnknown_Release(unknown);
1813 ok(ref == 2, "got %u\n", ref);
1815 hr = IMFAttributes_QueryInterface(attributes, &IID_IMFByteStream,
1816 (void **)&bytestream2);
1817 ok(hr == S_OK, "got 0x%08x\n", hr);
1818 ok(bytestream2 == bytestream, "got %p\n", bytestream2);
1819 ref = IMFByteStream_Release(bytestream2);
1820 ok(ref == 2, "got %u\n", ref);
1822 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1823 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1824 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1825 check_interface(bytestream, &IID_IMFGetService, FALSE);
1827 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1828 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1829 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1831 hr = IMFByteStream_Close(bytestream);
1832 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1834 hr = IMFByteStream_Close(bytestream);
1835 ok(hr == S_OK, "Failed to close, hr %#x.\n", hr);
1837 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1838 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1839 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1841 caps = 0;
1842 hr = IMFByteStream_Read(bytestream, (BYTE *)&caps, sizeof(caps), &size);
1843 ok(hr == S_OK, "Failed to read from stream, hr %#x.\n", hr);
1844 ok(caps == 0xffff0000, "Unexpected content.\n");
1846 IMFAttributes_Release(attributes);
1847 IMFByteStream_Release(bytestream);
1848 IStream_Release(stream);
1851 static void test_file_stream(void)
1853 static const WCHAR newfilename[] = L"new.mp4";
1854 IMFByteStream *bytestream, *bytestream2;
1855 QWORD bytestream_length, position;
1856 IMFAttributes *attributes = NULL;
1857 MF_ATTRIBUTE_TYPE item_type;
1858 WCHAR pathW[MAX_PATH];
1859 DWORD caps, count;
1860 WCHAR *filename;
1861 HRESULT hr;
1862 WCHAR *str;
1863 BOOL eos;
1865 filename = load_resource(L"test.mp4");
1867 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
1868 ok(hr == S_OK, "got 0x%08x\n", hr);
1870 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1871 MF_FILEFLAGS_NONE, filename, &bytestream);
1872 ok(hr == S_OK, "got 0x%08x\n", hr);
1874 check_interface(bytestream, &IID_IMFByteStreamBuffering, FALSE);
1875 check_interface(bytestream, &IID_IMFByteStreamCacheControl, FALSE);
1876 check_interface(bytestream, &IID_IMFMediaEventGenerator, FALSE);
1877 check_interface(bytestream, &IID_IMFGetService, TRUE);
1879 hr = IMFByteStream_GetCapabilities(bytestream, &caps);
1880 ok(hr == S_OK, "Failed to get stream capabilities, hr %#x.\n", hr);
1881 if (is_win8_plus)
1883 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
1884 "Unexpected caps %#x.\n", caps);
1886 else
1887 ok(caps == (MFBYTESTREAM_IS_READABLE | MFBYTESTREAM_IS_SEEKABLE), "Unexpected caps %#x.\n", caps);
1889 hr = IMFByteStream_QueryInterface(bytestream, &IID_IMFAttributes,
1890 (void **)&attributes);
1891 ok(hr == S_OK, "got 0x%08x\n", hr);
1892 ok(attributes != NULL, "got NULL\n");
1894 hr = IMFAttributes_GetCount(attributes, &count);
1895 ok(hr == S_OK, "Failed to get attributes count, hr %#x.\n", hr);
1896 ok(count == 2, "Unexpected attributes count %u.\n", count);
1898 /* Original file name. */
1899 hr = IMFAttributes_GetAllocatedString(attributes, &MF_BYTESTREAM_ORIGIN_NAME, &str, &count);
1900 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
1901 ok(!lstrcmpW(str, filename), "Unexpected name %s.\n", wine_dbgstr_w(str));
1902 CoTaskMemFree(str);
1904 /* Modification time. */
1905 hr = IMFAttributes_GetItemType(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, &item_type);
1906 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
1907 ok(item_type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
1909 IMFAttributes_Release(attributes);
1911 /* Length. */
1912 hr = IMFByteStream_GetLength(bytestream, NULL);
1913 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1915 bytestream_length = 0;
1916 hr = IMFByteStream_GetLength(bytestream, &bytestream_length);
1917 ok(hr == S_OK, "Failed to get bytestream length, hr %#x.\n", hr);
1918 ok(bytestream_length > 0, "Unexpected bytestream length %s.\n", wine_dbgstr_longlong(bytestream_length));
1920 hr = IMFByteStream_SetCurrentPosition(bytestream, bytestream_length);
1921 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1923 hr = IMFByteStream_IsEndOfStream(bytestream, &eos);
1924 ok(hr == S_OK, "Failed query end of stream, hr %#x.\n", hr);
1925 ok(eos == TRUE, "Unexpected IsEndOfStream result, %u.\n", eos);
1927 hr = IMFByteStream_SetCurrentPosition(bytestream, 2 * bytestream_length);
1928 ok(hr == S_OK, "Failed to set bytestream position, hr %#x.\n", hr);
1930 hr = IMFByteStream_GetCurrentPosition(bytestream, NULL);
1931 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
1933 hr = IMFByteStream_GetCurrentPosition(bytestream, &position);
1934 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
1935 ok(position == 2 * bytestream_length, "Unexpected position.\n");
1937 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1938 MF_FILEFLAGS_NONE, filename, &bytestream2);
1939 ok(hr == S_OK, "got 0x%08x\n", hr);
1940 IMFByteStream_Release(bytestream2);
1942 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1943 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1945 hr = MFCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &bytestream2);
1946 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1948 IMFByteStream_Release(bytestream);
1950 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1951 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1952 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
1954 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1955 MF_FILEFLAGS_NONE, filename, &bytestream);
1956 ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS), "got 0x%08x\n", hr);
1958 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_EXIST,
1959 MF_FILEFLAGS_NONE, newfilename, &bytestream);
1960 ok(hr == S_OK, "got 0x%08x\n", hr);
1962 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1963 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1965 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, newfilename, &bytestream2);
1966 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1968 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1969 newfilename, &bytestream2);
1970 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1972 IMFByteStream_Release(bytestream);
1974 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST,
1975 MF_FILEFLAGS_ALLOW_WRITE_SHARING, newfilename, &bytestream);
1976 ok(hr == S_OK, "got 0x%08x\n", hr);
1978 /* Opening the file again fails even though MF_FILEFLAGS_ALLOW_WRITE_SHARING is set. */
1979 hr = MFCreateFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_ALLOW_WRITE_SHARING,
1980 newfilename, &bytestream2);
1981 ok(hr == HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION), "Unexpected hr %#x.\n", hr);
1983 IMFByteStream_Release(bytestream);
1985 /* Explicit file: scheme */
1986 lstrcpyW(pathW, fileschemeW);
1987 lstrcatW(pathW, filename);
1988 hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, pathW, &bytestream);
1989 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
1991 hr = MFShutdown();
1992 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
1994 DeleteFileW(filename);
1995 DeleteFileW(newfilename);
1998 static void test_system_memory_buffer(void)
2000 IMFMediaBuffer *buffer;
2001 HRESULT hr;
2002 DWORD length, max;
2003 BYTE *data, *data2;
2005 hr = MFCreateMemoryBuffer(1024, NULL);
2006 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2008 hr = MFCreateMemoryBuffer(0, &buffer);
2009 ok(hr == S_OK, "got 0x%08x\n", hr);
2010 if(buffer)
2012 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2013 ok(hr == S_OK, "got 0x%08x\n", hr);
2014 ok(length == 0, "got %u\n", length);
2016 IMFMediaBuffer_Release(buffer);
2019 hr = MFCreateMemoryBuffer(1024, &buffer);
2020 ok(hr == S_OK, "got 0x%08x\n", hr);
2022 check_interface(buffer, &IID_IMFGetService, FALSE);
2024 hr = IMFMediaBuffer_GetMaxLength(buffer, NULL);
2025 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2027 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2028 ok(hr == S_OK, "got 0x%08x\n", hr);
2029 ok(length == 1024, "got %u\n", length);
2031 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1025);
2032 ok(hr == E_INVALIDARG, "got 0x%08x\n", hr);
2034 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2035 ok(hr == S_OK, "got 0x%08x\n", hr);
2037 hr = IMFMediaBuffer_GetCurrentLength(buffer, NULL);
2038 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2040 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2041 ok(hr == S_OK, "got 0x%08x\n", hr);
2042 ok(length == 10, "got %u\n", length);
2044 length = 0;
2045 max = 0;
2046 hr = IMFMediaBuffer_Lock(buffer, NULL, &length, &max);
2047 ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
2048 ok(length == 0, "got %u\n", length);
2049 ok(max == 0, "got %u\n", length);
2051 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2052 ok(hr == S_OK, "got 0x%08x\n", hr);
2053 ok(length == 10, "got %u\n", length);
2054 ok(max == 1024, "got %u\n", max);
2056 /* Attempt to lock the buffer twice */
2057 hr = IMFMediaBuffer_Lock(buffer, &data2, &max, &length);
2058 ok(hr == S_OK, "got 0x%08x\n", hr);
2059 ok(data == data2, "got 0x%08x\n", hr);
2061 hr = IMFMediaBuffer_Unlock(buffer);
2062 ok(hr == S_OK, "got 0x%08x\n", hr);
2064 hr = IMFMediaBuffer_Unlock(buffer);
2065 ok(hr == S_OK, "got 0x%08x\n", hr);
2067 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2068 ok(hr == S_OK, "got 0x%08x\n", hr);
2070 hr = IMFMediaBuffer_Unlock(buffer);
2071 ok(hr == S_OK, "got 0x%08x\n", hr);
2073 /* Extra Unlock */
2074 hr = IMFMediaBuffer_Unlock(buffer);
2075 ok(hr == S_OK, "got 0x%08x\n", hr);
2077 IMFMediaBuffer_Release(buffer);
2079 /* Aligned buffer. */
2080 hr = MFCreateAlignedMemoryBuffer(16, MF_8_BYTE_ALIGNMENT, NULL);
2081 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2083 hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer);
2084 ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr);
2086 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2087 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2088 ok(length == 0, "Unexpected current length %u.\n", length);
2090 hr = IMFMediaBuffer_SetCurrentLength(buffer, 1);
2091 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2092 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
2093 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2094 ok(length == 1, "Unexpected current length %u.\n", length);
2096 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2097 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2098 ok(length == 201, "Unexpected max length %u.\n", length);
2100 hr = IMFMediaBuffer_SetCurrentLength(buffer, 202);
2101 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2102 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
2103 ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr);
2104 ok(length == 201, "Unexpected max length %u.\n", length);
2105 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
2106 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2108 hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length);
2109 ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr);
2110 ok(max == 201 && length == 10, "Unexpected length.\n");
2111 hr = IMFMediaBuffer_Unlock(buffer);
2112 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2114 IMFMediaBuffer_Release(buffer);
2117 static void test_sample(void)
2119 static const DWORD test_pattern = 0x22222222;
2120 IMFMediaBuffer *buffer, *buffer2, *buffer3;
2121 DWORD count, flags, length;
2122 IMFAttributes *attributes;
2123 IMFSample *sample;
2124 LONGLONG time;
2125 HRESULT hr;
2126 BYTE *data;
2128 hr = MFCreateSample( &sample );
2129 ok(hr == S_OK, "got 0x%08x\n", hr);
2131 hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes);
2132 ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr);
2134 CHECK_ATTR_COUNT(attributes, 0);
2136 hr = IMFSample_GetBufferCount(sample, NULL);
2137 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2139 hr = IMFSample_GetBufferCount(sample, &count);
2140 ok(hr == S_OK, "got 0x%08x\n", hr);
2141 ok(count == 0, "got %d\n", count);
2143 hr = IMFSample_GetSampleFlags(sample, &flags);
2144 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2145 ok(!flags, "Unexpected flags %#x.\n", flags);
2147 hr = IMFSample_SetSampleFlags(sample, 0x123);
2148 ok(hr == S_OK, "Failed to set sample flags, hr %#x.\n", hr);
2149 hr = IMFSample_GetSampleFlags(sample, &flags);
2150 ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr);
2151 ok(flags == 0x123, "Unexpected flags %#x.\n", flags);
2153 hr = IMFSample_GetSampleTime(sample, &time);
2154 ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr);
2156 hr = IMFSample_GetSampleDuration(sample, &time);
2157 ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr);
2159 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
2160 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2162 hr = IMFSample_RemoveBufferByIndex(sample, 0);
2163 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2165 hr = IMFSample_RemoveAllBuffers(sample);
2166 ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr);
2168 hr = IMFSample_GetTotalLength(sample, &length);
2169 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2170 ok(!length, "Unexpected total length %u.\n", length);
2172 hr = MFCreateMemoryBuffer(16, &buffer);
2173 ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr);
2175 hr = IMFSample_AddBuffer(sample, buffer);
2176 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2178 hr = IMFSample_AddBuffer(sample, buffer);
2179 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2181 hr = IMFSample_GetBufferCount(sample, &count);
2182 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2183 ok(count == 2, "Unexpected buffer count %u.\n", count);
2185 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2);
2186 ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr);
2187 ok(buffer2 == buffer, "Unexpected object.\n");
2188 IMFMediaBuffer_Release(buffer2);
2190 hr = IMFSample_GetTotalLength(sample, &length);
2191 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2192 ok(!length, "Unexpected total length %u.\n", length);
2194 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2);
2195 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2197 hr = IMFSample_GetTotalLength(sample, &length);
2198 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2199 ok(length == 4, "Unexpected total length %u.\n", length);
2201 hr = IMFSample_RemoveBufferByIndex(sample, 1);
2202 ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr);
2204 hr = IMFSample_GetTotalLength(sample, &length);
2205 ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr);
2206 ok(length == 2, "Unexpected total length %u.\n", length);
2208 IMFMediaBuffer_Release(buffer);
2210 /* Duration */
2211 hr = IMFSample_SetSampleDuration(sample, 10);
2212 ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr);
2213 CHECK_ATTR_COUNT(attributes, 0);
2214 hr = IMFSample_GetSampleDuration(sample, &time);
2215 ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr);
2216 ok(time == 10, "Unexpected duration.\n");
2218 /* Timestamp */
2219 hr = IMFSample_SetSampleTime(sample, 1);
2220 ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr);
2221 CHECK_ATTR_COUNT(attributes, 0);
2222 hr = IMFSample_GetSampleTime(sample, &time);
2223 ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr);
2224 ok(time == 1, "Unexpected timestamp.\n");
2226 IMFAttributes_Release(attributes);
2227 IMFSample_Release(sample);
2229 /* CopyToBuffer() */
2230 hr = MFCreateSample(&sample);
2231 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2233 hr = MFCreateMemoryBuffer(16, &buffer2);
2234 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2236 /* Sample with no buffers. */
2237 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2238 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2239 hr = IMFSample_CopyToBuffer(sample, buffer2);
2240 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2241 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2242 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
2243 ok(!length, "Unexpected length %u.\n", length);
2245 /* Single buffer, larger destination. */
2246 hr = MFCreateMemoryBuffer(8, &buffer);
2247 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2249 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
2250 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2251 *(DWORD *)data = 0x11111111;
2252 hr = IMFMediaBuffer_Unlock(buffer);
2253 ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr);
2254 hr = IMFMediaBuffer_SetCurrentLength(buffer, 4);
2255 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2257 hr = IMFSample_AddBuffer(sample, buffer);
2258 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2260 /* Existing content is overwritten. */
2261 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 8);
2262 ok(hr == S_OK, "Failed to set length, hr %#x.\n", hr);
2264 hr = IMFSample_CopyToBuffer(sample, buffer2);
2265 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2267 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2268 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2269 ok(length == 4, "Unexpected buffer length %u.\n", length);
2271 /* Multiple buffers, matching total size. */
2272 hr = IMFSample_AddBuffer(sample, buffer);
2273 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2275 hr = IMFSample_GetBufferCount(sample, &count);
2276 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2277 ok(count == 2, "Unexpected buffer count %u.\n", count);
2279 hr = IMFMediaBuffer_SetCurrentLength(buffer, 8);
2280 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
2282 hr = IMFSample_CopyToBuffer(sample, buffer2);
2283 ok(hr == S_OK, "Failed to copy to buffer, hr %#x.\n", hr);
2285 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2286 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2287 ok(length == 16, "Unexpected buffer length %u.\n", length);
2289 hr = IMFSample_AddBuffer(sample, buffer);
2290 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2292 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 1);
2293 ok(hr == S_OK, "Failed to set buffer length, hr %#x.\n", hr);
2295 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2296 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2297 *(DWORD *)data = test_pattern;
2298 hr = IMFMediaBuffer_Unlock(buffer2);
2299 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2301 hr = IMFSample_CopyToBuffer(sample, buffer2);
2302 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
2304 hr = IMFMediaBuffer_Lock(buffer2, &data, NULL, NULL);
2305 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
2306 ok(!memcmp(data, &test_pattern, sizeof(test_pattern)), "Unexpected contents, %#x\n", *(DWORD *)data);
2307 hr = IMFMediaBuffer_Unlock(buffer2);
2308 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
2310 hr = IMFMediaBuffer_GetCurrentLength(buffer2, &length);
2311 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
2312 ok(!length, "Unexpected buffer length %u.\n", length);
2314 IMFMediaBuffer_Release(buffer2);
2315 IMFSample_Release(sample);
2317 /* ConvertToContiguousBuffer() */
2318 hr = MFCreateSample(&sample);
2319 ok(hr == S_OK, "Failed to create a sample, hr %#x.\n", hr);
2321 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer);
2322 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2324 hr = MFCreateMemoryBuffer(16, &buffer);
2325 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2327 hr = IMFSample_AddBuffer(sample, buffer);
2328 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2330 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2331 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2332 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2333 IMFMediaBuffer_Release(buffer2);
2335 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2336 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2338 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2);
2339 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2340 ok(buffer2 == buffer, "Unexpected buffer instance.\n");
2341 IMFMediaBuffer_Release(buffer2);
2343 hr = IMFMediaBuffer_SetCurrentLength(buffer, 3);
2344 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2346 hr = MFCreateMemoryBuffer(16, &buffer2);
2347 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
2349 hr = IMFMediaBuffer_SetCurrentLength(buffer2, 4);
2350 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2352 hr = IMFSample_AddBuffer(sample, buffer2);
2353 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2354 IMFMediaBuffer_Release(buffer2);
2356 hr = IMFSample_GetBufferCount(sample, &count);
2357 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2358 ok(count == 2, "Unexpected buffer count %u.\n", count);
2360 hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer3);
2361 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2363 hr = IMFMediaBuffer_GetMaxLength(buffer3, &length);
2364 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2365 ok(length == 7, "Unexpected length %u.\n", length);
2367 hr = IMFMediaBuffer_GetCurrentLength(buffer3, &length);
2368 ok(hr == S_OK, "Failed to get maximum length, hr %#x.\n", hr);
2369 ok(length == 7, "Unexpected length %u.\n", length);
2371 IMFMediaBuffer_Release(buffer3);
2373 hr = IMFSample_GetBufferCount(sample, &count);
2374 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2375 ok(count == 1, "Unexpected buffer count %u.\n", count);
2377 hr = IMFSample_AddBuffer(sample, buffer);
2378 ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr);
2380 hr = IMFSample_GetBufferCount(sample, &count);
2381 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2382 ok(count == 2, "Unexpected buffer count %u.\n", count);
2384 hr = IMFSample_ConvertToContiguousBuffer(sample, NULL);
2385 ok(hr == S_OK, "Failed to convert, hr %#x.\n", hr);
2387 hr = IMFSample_GetBufferCount(sample, &count);
2388 ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr);
2389 ok(count == 1, "Unexpected buffer count %u.\n", count);
2391 IMFMediaBuffer_Release(buffer);
2393 IMFSample_Release(sample);
2396 static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
2398 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
2399 IMFMediaEventQueue *queue;
2400 IUnknown *state, *obj;
2401 HRESULT hr;
2403 ok(result != NULL, "Unexpected result object.\n");
2405 state = IMFAsyncResult_GetStateNoAddRef(result);
2406 if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue)))
2408 IMFMediaEvent *event = NULL, *event2;
2410 if (is_win8_plus)
2412 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
2413 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2415 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event);
2416 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr);
2418 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
2419 ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr);
2421 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event2);
2422 ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr);
2424 if (event)
2425 IMFMediaEvent_Release(event);
2428 hr = IMFAsyncResult_GetObject(result, &obj);
2429 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2431 IMFMediaEventQueue_Release(queue);
2433 SetEvent(callback->event);
2436 return E_NOTIMPL;
2439 static const IMFAsyncCallbackVtbl testcallbackvtbl =
2441 testcallback_QueryInterface,
2442 testcallback_AddRef,
2443 testcallback_Release,
2444 testcallback_GetParameters,
2445 testcallback_Invoke,
2448 static void init_test_callback(struct test_callback *callback)
2450 callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl;
2451 callback->event = NULL;
2454 static void test_MFCreateAsyncResult(void)
2456 IMFAsyncResult *result, *result2;
2457 struct test_callback callback;
2458 IUnknown *state, *object;
2459 MFASYNCRESULT *data;
2460 ULONG refcount;
2461 HANDLE event;
2462 DWORD flags;
2463 HRESULT hr;
2464 BOOL ret;
2466 init_test_callback(&callback);
2468 hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL);
2469 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2471 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2472 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2474 data = (MFASYNCRESULT *)result;
2475 ok(data->pCallback == NULL, "Unexpected callback value.\n");
2476 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2477 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2478 ok(data->hEvent == NULL, "Unexpected event.\n");
2480 hr = IMFAsyncResult_GetState(result, NULL);
2481 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2483 state = (void *)0xdeadbeef;
2484 hr = IMFAsyncResult_GetState(result, &state);
2485 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2486 ok(state == (void *)0xdeadbeef, "Unexpected state.\n");
2488 hr = IMFAsyncResult_GetStatus(result);
2489 ok(hr == S_OK, "Unexpected status %#x.\n", hr);
2491 data->hrStatusResult = 123;
2492 hr = IMFAsyncResult_GetStatus(result);
2493 ok(hr == 123, "Unexpected status %#x.\n", hr);
2495 hr = IMFAsyncResult_SetStatus(result, E_FAIL);
2496 ok(hr == S_OK, "Failed to set status, hr %#x.\n", hr);
2497 ok(data->hrStatusResult == E_FAIL, "Unexpected status %#x.\n", hr);
2499 hr = IMFAsyncResult_GetObject(result, NULL);
2500 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2502 object = (void *)0xdeadbeef;
2503 hr = IMFAsyncResult_GetObject(result, &object);
2504 ok(hr == E_POINTER, "Failed to get object, hr %#x.\n", hr);
2505 ok(object == (void *)0xdeadbeef, "Unexpected object.\n");
2507 state = IMFAsyncResult_GetStateNoAddRef(result);
2508 ok(state == NULL, "Unexpected state.\n");
2510 /* Object. */
2511 hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2);
2512 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2514 data = (MFASYNCRESULT *)result2;
2515 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2516 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2517 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2518 ok(data->hEvent == NULL, "Unexpected event.\n");
2520 object = NULL;
2521 hr = IMFAsyncResult_GetObject(result2, &object);
2522 ok(hr == S_OK, "Failed to get object, hr %#x.\n", hr);
2523 ok(object == (IUnknown *)result, "Unexpected object.\n");
2524 IUnknown_Release(object);
2526 IMFAsyncResult_Release(result2);
2528 /* State object. */
2529 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2);
2530 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2532 data = (MFASYNCRESULT *)result2;
2533 ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n");
2534 ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult);
2535 ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred);
2536 ok(data->hEvent == NULL, "Unexpected event.\n");
2538 state = NULL;
2539 hr = IMFAsyncResult_GetState(result2, &state);
2540 ok(hr == S_OK, "Failed to get state object, hr %#x.\n", hr);
2541 ok(state == (IUnknown *)result, "Unexpected state.\n");
2542 IUnknown_Release(state);
2544 state = IMFAsyncResult_GetStateNoAddRef(result2);
2545 ok(state == (IUnknown *)result, "Unexpected state.\n");
2547 refcount = IMFAsyncResult_Release(result2);
2548 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2549 refcount = IMFAsyncResult_Release(result);
2550 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2552 /* Event handle is closed on release. */
2553 hr = MFCreateAsyncResult(NULL, NULL, NULL, &result);
2554 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2556 data = (MFASYNCRESULT *)result;
2557 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2558 ok(data->hEvent != NULL, "Failed to create event.\n");
2559 ret = GetHandleInformation(event, &flags);
2560 ok(ret, "Failed to get handle info.\n");
2562 refcount = IMFAsyncResult_Release(result);
2563 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2564 ret = GetHandleInformation(event, &flags);
2565 ok(!ret, "Expected handle to be closed.\n");
2567 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2568 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
2570 data = (MFASYNCRESULT *)result;
2571 data->hEvent = event = CreateEventA(NULL, FALSE, FALSE, NULL);
2572 ok(data->hEvent != NULL, "Failed to create event.\n");
2573 ret = GetHandleInformation(event, &flags);
2574 ok(ret, "Failed to get handle info.\n");
2576 refcount = IMFAsyncResult_Release(result);
2577 ok(!refcount, "Unexpected refcount %u.\n", refcount);
2578 ret = GetHandleInformation(event, &flags);
2579 ok(!ret, "Expected handle to be closed.\n");
2582 static void test_startup(void)
2584 DWORD queue;
2585 HRESULT hr;
2587 hr = MFStartup(MAKELONG(MF_API_VERSION, 0xdead), MFSTARTUP_FULL);
2588 ok(hr == MF_E_BAD_STARTUP_VERSION, "Unexpected hr %#x.\n", hr);
2590 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2591 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2593 hr = MFAllocateWorkQueue(&queue);
2594 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2595 hr = MFUnlockWorkQueue(queue);
2596 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2598 hr = MFShutdown();
2599 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2601 hr = MFAllocateWorkQueue(&queue);
2602 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2604 /* Already shut down, has no effect. */
2605 hr = MFShutdown();
2606 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2608 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2609 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2611 hr = MFAllocateWorkQueue(&queue);
2612 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2613 hr = MFUnlockWorkQueue(queue);
2614 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2616 hr = MFShutdown();
2617 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2619 /* Platform lock. */
2620 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2621 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2623 hr = MFAllocateWorkQueue(&queue);
2624 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2625 hr = MFUnlockWorkQueue(queue);
2626 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2628 /* Unlocking implies shutdown. */
2629 hr = MFUnlockPlatform();
2630 ok(hr == S_OK, "Failed to unlock, %#x.\n", hr);
2632 hr = MFAllocateWorkQueue(&queue);
2633 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
2635 hr = MFLockPlatform();
2636 ok(hr == S_OK, "Failed to lock, %#x.\n", hr);
2638 hr = MFAllocateWorkQueue(&queue);
2639 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2640 hr = MFUnlockWorkQueue(queue);
2641 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2643 hr = MFShutdown();
2644 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2647 static void test_allocate_queue(void)
2649 DWORD queue, queue2;
2650 HRESULT hr;
2652 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2653 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2655 hr = MFAllocateWorkQueue(&queue);
2656 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2657 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2659 hr = MFUnlockWorkQueue(queue);
2660 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2662 hr = MFUnlockWorkQueue(queue);
2663 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
2665 hr = MFAllocateWorkQueue(&queue2);
2666 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2667 ok(queue2 & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
2669 hr = MFUnlockWorkQueue(queue2);
2670 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2672 /* Unlock in system queue range. */
2673 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD);
2674 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2676 hr = MFUnlockWorkQueue(MFASYNC_CALLBACK_QUEUE_UNDEFINED);
2677 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2679 hr = MFUnlockWorkQueue(0x20);
2680 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
2682 hr = MFShutdown();
2683 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2686 static void test_MFCopyImage(void)
2688 BYTE dest[16], src[16];
2689 HRESULT hr;
2691 if (!pMFCopyImage)
2693 win_skip("MFCopyImage() is not available.\n");
2694 return;
2697 memset(dest, 0xaa, sizeof(dest));
2698 memset(src, 0x11, sizeof(src));
2700 hr = pMFCopyImage(dest, 8, src, 8, 4, 1);
2701 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2702 ok(!memcmp(dest, src, 4) && dest[4] == 0xaa, "Unexpected buffer contents.\n");
2704 memset(dest, 0xaa, sizeof(dest));
2705 memset(src, 0x11, sizeof(src));
2707 hr = pMFCopyImage(dest, 8, src, 8, 16, 1);
2708 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2709 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2711 memset(dest, 0xaa, sizeof(dest));
2712 memset(src, 0x11, sizeof(src));
2714 hr = pMFCopyImage(dest, 8, src, 8, 8, 2);
2715 ok(hr == S_OK, "Failed to copy image %#x.\n", hr);
2716 ok(!memcmp(dest, src, 16), "Unexpected buffer contents.\n");
2719 static void test_MFCreateCollection(void)
2721 IMFCollection *collection;
2722 IUnknown *element;
2723 DWORD count;
2724 HRESULT hr;
2726 hr = MFCreateCollection(NULL);
2727 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2729 hr = MFCreateCollection(&collection);
2730 ok(hr == S_OK, "Failed to create collection, hr %#x.\n", hr);
2732 hr = IMFCollection_GetElementCount(collection, NULL);
2733 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2735 count = 1;
2736 hr = IMFCollection_GetElementCount(collection, &count);
2737 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2738 ok(count == 0, "Unexpected count %u.\n", count);
2740 hr = IMFCollection_GetElement(collection, 0, NULL);
2741 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2743 element = (void *)0xdeadbeef;
2744 hr = IMFCollection_GetElement(collection, 0, &element);
2745 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
2746 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2748 hr = IMFCollection_RemoveElement(collection, 0, NULL);
2749 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
2751 element = (void *)0xdeadbeef;
2752 hr = IMFCollection_RemoveElement(collection, 0, &element);
2753 ok(hr == E_INVALIDARG, "Failed to remove element, hr %#x.\n", hr);
2754 ok(element == (void *)0xdeadbeef, "Unexpected pointer.\n");
2756 hr = IMFCollection_RemoveAllElements(collection);
2757 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2759 hr = IMFCollection_AddElement(collection, (IUnknown *)collection);
2760 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2762 count = 0;
2763 hr = IMFCollection_GetElementCount(collection, &count);
2764 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2765 ok(count == 1, "Unexpected count %u.\n", count);
2767 hr = IMFCollection_AddElement(collection, NULL);
2768 ok(hr == S_OK, "Failed to add element, hr %#x.\n", hr);
2770 count = 0;
2771 hr = IMFCollection_GetElementCount(collection, &count);
2772 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2773 ok(count == 2, "Unexpected count %u.\n", count);
2775 hr = IMFCollection_InsertElementAt(collection, 10, (IUnknown *)collection);
2776 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2778 count = 0;
2779 hr = IMFCollection_GetElementCount(collection, &count);
2780 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2781 ok(count == 11, "Unexpected count %u.\n", count);
2783 hr = IMFCollection_GetElement(collection, 0, &element);
2784 ok(hr == S_OK, "Failed to get element, hr %#x.\n", hr);
2785 ok(element == (IUnknown *)collection, "Unexpected element.\n");
2786 IUnknown_Release(element);
2788 hr = IMFCollection_GetElement(collection, 1, &element);
2789 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2790 ok(!element, "Unexpected element.\n");
2792 hr = IMFCollection_GetElement(collection, 2, &element);
2793 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2794 ok(!element, "Unexpected element.\n");
2796 hr = IMFCollection_GetElement(collection, 10, &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_InsertElementAt(collection, 0, NULL);
2802 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2804 hr = IMFCollection_GetElement(collection, 0, &element);
2805 ok(hr == E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
2807 hr = IMFCollection_RemoveAllElements(collection);
2808 ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
2810 count = 1;
2811 hr = IMFCollection_GetElementCount(collection, &count);
2812 ok(hr == S_OK, "Failed to get element count, hr %#x.\n", hr);
2813 ok(count == 0, "Unexpected count %u.\n", count);
2815 hr = IMFCollection_InsertElementAt(collection, 0, NULL);
2816 ok(hr == S_OK, "Failed to insert element, hr %#x.\n", hr);
2818 IMFCollection_Release(collection);
2821 static void test_MFHeapAlloc(void)
2823 void *res;
2825 res = MFHeapAlloc(16, 0, NULL, 0, eAllocationTypeIgnore);
2826 ok(res != NULL, "MFHeapAlloc failed.\n");
2828 MFHeapFree(res);
2831 static void test_scheduled_items(void)
2833 struct test_callback callback;
2834 IMFAsyncResult *result;
2835 MFWORKITEM_KEY key, key2;
2836 HRESULT hr;
2838 init_test_callback(&callback);
2840 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2841 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2843 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2844 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2846 hr = MFCancelWorkItem(key);
2847 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2849 hr = MFCancelWorkItem(key);
2850 ok(hr == MF_E_NOT_FOUND || broken(hr == S_OK) /* < win10 */, "Unexpected hr %#x.\n", hr);
2852 if (!pMFPutWaitingWorkItem)
2854 win_skip("Waiting items are not supported.\n");
2855 return;
2858 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
2859 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
2861 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key);
2862 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2864 hr = pMFPutWaitingWorkItem(NULL, 0, result, &key2);
2865 ok(hr == S_OK, "Failed to add waiting item, hr %#x.\n", hr);
2867 hr = MFCancelWorkItem(key);
2868 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2870 hr = MFCancelWorkItem(key2);
2871 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2873 IMFAsyncResult_Release(result);
2875 hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key);
2876 ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
2878 hr = MFCancelWorkItem(key);
2879 ok(hr == S_OK, "Failed to cancel item, hr %#x.\n", hr);
2881 hr = MFShutdown();
2882 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2885 static void test_serial_queue(void)
2887 static const DWORD queue_ids[] =
2889 MFASYNC_CALLBACK_QUEUE_STANDARD,
2890 MFASYNC_CALLBACK_QUEUE_RT,
2891 MFASYNC_CALLBACK_QUEUE_IO,
2892 MFASYNC_CALLBACK_QUEUE_TIMER,
2893 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
2894 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
2896 DWORD queue, serial_queue;
2897 unsigned int i;
2898 HRESULT hr;
2900 if (!pMFAllocateSerialWorkQueue)
2902 win_skip("Serial queues are not supported.\n");
2903 return;
2906 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2907 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2909 for (i = 0; i < ARRAY_SIZE(queue_ids); ++i)
2911 BOOL broken_types = queue_ids[i] == MFASYNC_CALLBACK_QUEUE_TIMER ||
2912 queue_ids[i] == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION;
2914 hr = pMFAllocateSerialWorkQueue(queue_ids[i], &serial_queue);
2915 ok(hr == S_OK || broken(broken_types && hr == E_INVALIDARG) /* Win8 */,
2916 "%u: failed to allocate a queue, hr %#x.\n", i, hr);
2918 if (SUCCEEDED(hr))
2920 hr = MFUnlockWorkQueue(serial_queue);
2921 ok(hr == S_OK, "%u: failed to unlock the queue, hr %#x.\n", i, hr);
2925 /* Chain them together. */
2926 hr = pMFAllocateSerialWorkQueue(MFASYNC_CALLBACK_QUEUE_STANDARD, &serial_queue);
2927 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2929 hr = pMFAllocateSerialWorkQueue(serial_queue, &queue);
2930 ok(hr == S_OK, "Failed to allocate a queue, hr %#x.\n", hr);
2932 hr = MFUnlockWorkQueue(serial_queue);
2933 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2935 hr = MFUnlockWorkQueue(queue);
2936 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
2938 hr = MFShutdown();
2939 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2942 static LONG periodic_counter;
2943 static void CALLBACK periodic_callback(IUnknown *context)
2945 InterlockedIncrement(&periodic_counter);
2948 static void test_periodic_callback(void)
2950 DWORD period, key;
2951 HRESULT hr;
2953 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2954 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
2956 period = 0;
2957 hr = MFGetTimerPeriodicity(&period);
2958 ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr);
2959 ok(period == 10, "Unexpected period %u.\n", period);
2961 if (!pMFAddPeriodicCallback)
2963 win_skip("Periodic callbacks are not supported.\n");
2964 hr = MFShutdown();
2965 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2966 return;
2969 ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter);
2971 hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key);
2972 ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr);
2973 ok(key != 0, "Unexpected key %#x.\n", key);
2975 Sleep(10 * period);
2977 hr = pMFRemovePeriodicCallback(key);
2978 ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr);
2980 ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter);
2982 hr = MFShutdown();
2983 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
2986 static void test_event_queue(void)
2988 struct test_callback callback, callback2;
2989 IMFMediaEvent *event, *event2;
2990 IMFMediaEventQueue *queue;
2991 IMFAsyncResult *result;
2992 HRESULT hr;
2993 DWORD ret;
2995 init_test_callback(&callback);
2996 init_test_callback(&callback2);
2998 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
2999 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3001 hr = MFCreateEventQueue(&queue);
3002 ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr);
3004 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3005 ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr);
3007 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3008 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3010 if (is_win8_plus)
3012 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3013 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3015 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2);
3016 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3017 ok(event2 == event, "Unexpected event object.\n");
3018 IMFMediaEvent_Release(event2);
3020 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3021 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3023 hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2);
3024 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3025 IMFMediaEvent_Release(event2);
3028 /* Async case. */
3029 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3030 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3032 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3033 ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr);
3035 /* Same callback, same state. */
3036 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue);
3037 ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3039 /* Same callback, different state. */
3040 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback);
3041 ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr);
3043 /* Different callback, same state. */
3044 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue);
3045 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3047 /* Different callback, different state. */
3048 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface);
3049 ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr);
3051 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
3053 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3054 ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr);
3056 ret = WaitForSingleObject(callback.event, 500);
3057 ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret);
3059 CloseHandle(callback.event);
3061 IMFMediaEvent_Release(event);
3063 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3064 ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
3066 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3067 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
3069 /* Shutdown behavior. */
3070 hr = IMFMediaEventQueue_Shutdown(queue);
3071 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3073 hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event);
3074 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3076 hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event);
3077 ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr);
3078 hr = IMFMediaEventQueue_QueueEvent(queue, event);
3079 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3080 IMFMediaEvent_Release(event);
3082 hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3083 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3085 hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL);
3086 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3088 hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL);
3089 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3091 hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL);
3092 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3094 hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event);
3095 ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
3096 IMFAsyncResult_Release(result);
3098 /* Already shut down. */
3099 hr = IMFMediaEventQueue_Shutdown(queue);
3100 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3102 IMFMediaEventQueue_Release(queue);
3104 hr = MFShutdown();
3105 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3108 static void test_presentation_descriptor(void)
3110 IMFStreamDescriptor *stream_desc[2], *stream_desc2;
3111 IMFPresentationDescriptor *pd, *pd2;
3112 IMFMediaType *media_type;
3113 unsigned int i;
3114 BOOL selected;
3115 UINT64 value;
3116 DWORD count;
3117 HRESULT hr;
3119 hr = MFCreateMediaType(&media_type);
3120 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3122 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3124 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]);
3125 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3128 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3129 ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
3131 hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count);
3132 ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count);
3134 for (i = 0; i < count; ++i)
3136 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2);
3137 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3138 ok(!selected, "Unexpected selected state.\n");
3139 ok(stream_desc[i] == stream_desc2, "Unexpected object.\n");
3140 IMFStreamDescriptor_Release(stream_desc2);
3143 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2);
3144 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3146 hr = IMFPresentationDescriptor_SelectStream(pd, 10);
3147 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3149 hr = IMFPresentationDescriptor_SelectStream(pd, 0);
3150 ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr);
3152 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2);
3153 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3154 ok(!!selected, "Unexpected selected state.\n");
3155 IMFStreamDescriptor_Release(stream_desc2);
3157 hr = IMFPresentationDescriptor_SetUINT64(pd, &MF_PD_TOTAL_FILE_SIZE, 1);
3158 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3160 hr = IMFPresentationDescriptor_Clone(pd, &pd2);
3161 ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr);
3163 hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2);
3164 ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
3165 ok(!!selected, "Unexpected selected state.\n");
3166 ok(stream_desc2 == stream_desc[0], "Unexpected stream descriptor.\n");
3167 IMFStreamDescriptor_Release(stream_desc2);
3169 value = 0;
3170 hr = IMFPresentationDescriptor_GetUINT64(pd2, &MF_PD_TOTAL_FILE_SIZE, &value);
3171 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
3172 ok(value == 1, "Unexpected attribute value.\n");
3174 IMFPresentationDescriptor_Release(pd2);
3175 IMFPresentationDescriptor_Release(pd);
3177 for (i = 0; i < ARRAY_SIZE(stream_desc); ++i)
3179 IMFStreamDescriptor_Release(stream_desc[i]);
3182 /* Partially initialized array. */
3183 hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]);
3184 ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
3185 stream_desc[0] = NULL;
3187 hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd);
3188 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3190 IMFStreamDescriptor_Release(stream_desc[1]);
3191 IMFMediaType_Release(media_type);
3194 enum clock_action
3196 CLOCK_START,
3197 CLOCK_STOP,
3198 CLOCK_PAUSE,
3199 CLOCK_RESTART,
3202 static void test_system_time_source(void)
3204 static const struct clock_state_test
3206 enum clock_action action;
3207 MFCLOCK_STATE state;
3208 BOOL is_invalid;
3210 clock_state_change[] =
3212 { CLOCK_STOP, MFCLOCK_STATE_INVALID },
3213 { CLOCK_RESTART, MFCLOCK_STATE_INVALID, TRUE },
3214 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3215 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED, TRUE },
3216 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3217 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3218 { CLOCK_RESTART, MFCLOCK_STATE_STOPPED, TRUE },
3219 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3220 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3221 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3222 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3223 { CLOCK_START, MFCLOCK_STATE_RUNNING },
3224 { CLOCK_PAUSE, MFCLOCK_STATE_PAUSED },
3225 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING },
3226 { CLOCK_RESTART, MFCLOCK_STATE_RUNNING, TRUE },
3227 { CLOCK_STOP, MFCLOCK_STATE_STOPPED },
3228 { CLOCK_PAUSE, MFCLOCK_STATE_STOPPED, TRUE },
3230 IMFPresentationTimeSource *time_source, *time_source2;
3231 IMFClockStateSink *statesink;
3232 IMFClock *clock, *clock2;
3233 MFCLOCK_PROPERTIES props;
3234 MFCLOCK_STATE state;
3235 unsigned int i;
3236 MFTIME systime;
3237 LONGLONG time;
3238 DWORD value;
3239 HRESULT hr;
3241 hr = MFCreateSystemTimeSource(&time_source);
3242 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3244 hr = IMFPresentationTimeSource_GetClockCharacteristics(time_source, &value);
3245 ok(hr == S_OK, "Failed to get flags, hr %#x.\n", hr);
3246 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK),
3247 "Unexpected flags %#x.\n", value);
3249 value = 1;
3250 hr = IMFPresentationTimeSource_GetContinuityKey(time_source, &value);
3251 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3252 ok(value == 0, "Unexpected value %u.\n", value);
3254 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3255 ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr);
3256 ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state);
3258 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3259 ok(hr == S_OK, "Failed to get state sink, hr %#x.\n", hr);
3261 /* State changes. */
3262 for (i = 0; i < ARRAY_SIZE(clock_state_change); ++i)
3264 switch (clock_state_change[i].action)
3266 case CLOCK_STOP:
3267 hr = IMFClockStateSink_OnClockStop(statesink, 0);
3268 break;
3269 case CLOCK_RESTART:
3270 hr = IMFClockStateSink_OnClockRestart(statesink, 0);
3271 break;
3272 case CLOCK_PAUSE:
3273 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3274 break;
3275 case CLOCK_START:
3276 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3277 break;
3278 default:
3281 ok(hr == (clock_state_change[i].is_invalid ? MF_E_INVALIDREQUEST : S_OK), "%u: unexpected hr %#x.\n", i, hr);
3282 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3283 ok(hr == S_OK, "%u: failed to get state, hr %#x.\n", i, hr);
3284 ok(state == clock_state_change[i].state, "%u: unexpected state %d.\n", i, state);
3287 IMFClockStateSink_Release(statesink);
3289 /* Properties. */
3290 hr = IMFPresentationTimeSource_GetProperties(time_source, NULL);
3291 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3293 hr = IMFPresentationTimeSource_GetProperties(time_source, &props);
3294 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3296 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3297 wine_dbgstr_longlong(props.qwCorrelationRate));
3298 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3299 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3300 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3301 wine_dbgstr_longlong(props.qwClockFrequency));
3302 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3303 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3305 /* Underlying clock. */
3306 hr = MFCreateSystemTimeSource(&time_source2);
3307 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3308 EXPECT_REF(time_source2, 1);
3309 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source2, &clock2);
3310 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3311 EXPECT_REF(time_source2, 1);
3312 EXPECT_REF(clock2, 2);
3314 EXPECT_REF(time_source, 1);
3315 hr = IMFPresentationTimeSource_GetUnderlyingClock(time_source, &clock);
3316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3317 EXPECT_REF(time_source, 1);
3318 EXPECT_REF(clock, 2);
3320 ok(clock != clock2, "Unexpected clock instance.\n");
3322 IMFPresentationTimeSource_Release(time_source2);
3323 IMFClock_Release(clock2);
3325 hr = IMFClock_GetClockCharacteristics(clock, &value);
3326 ok(hr == S_OK, "Failed to get clock flags, hr %#x.\n", hr);
3327 ok(value == (MFCLOCK_CHARACTERISTICS_FLAG_FREQUENCY_10MHZ | MFCLOCK_CHARACTERISTICS_FLAG_ALWAYS_RUNNING |
3328 MFCLOCK_CHARACTERISTICS_FLAG_IS_SYSTEM_CLOCK), "Unexpected flags %#x.\n", value);
3330 hr = IMFClock_GetContinuityKey(clock, &value);
3331 ok(hr == S_OK, "Failed to get clock key, hr %#x.\n", hr);
3332 ok(value == 0, "Unexpected key value %u.\n", value);
3334 hr = IMFClock_GetState(clock, 0, &state);
3335 ok(hr == S_OK, "Failed to get clock state, hr %#x.\n", hr);
3336 ok(state == MFCLOCK_STATE_RUNNING, "Unexpected state %d.\n", state);
3338 hr = IMFClock_GetProperties(clock, &props);
3339 ok(hr == S_OK, "Failed to get clock properties, hr %#x.\n", hr);
3341 ok(props.qwCorrelationRate == 0, "Unexpected correlation rate %s.\n",
3342 wine_dbgstr_longlong(props.qwCorrelationRate));
3343 ok(IsEqualGUID(&props.guidClockId, &GUID_NULL), "Unexpected clock id %s.\n", wine_dbgstr_guid(&props.guidClockId));
3344 ok(props.dwClockFlags == 0, "Unexpected flags %#x.\n", props.dwClockFlags);
3345 ok(props.qwClockFrequency == MFCLOCK_FREQUENCY_HNS, "Unexpected frequency %s.\n",
3346 wine_dbgstr_longlong(props.qwClockFrequency));
3347 ok(props.dwClockTolerance == MFCLOCK_TOLERANCE_UNKNOWN, "Unexpected tolerance %u.\n", props.dwClockTolerance);
3348 ok(props.dwClockJitter == 1, "Unexpected jitter %u.\n", props.dwClockJitter);
3350 hr = IMFClock_GetCorrelatedTime(clock, 0, &time, &systime);
3351 ok(hr == S_OK, "Failed to get clock time, hr %#x.\n", hr);
3352 ok(time == systime, "Unexpected time %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3354 IMFClock_Release(clock);
3356 /* Test returned time regarding specified rate and offset. */
3357 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3358 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3360 hr = IMFPresentationTimeSource_GetState(time_source, 0, &state);
3361 ok(hr == S_OK, "Failed to get state %#x.\n", hr);
3362 ok(state == MFCLOCK_STATE_STOPPED, "Unexpected state %d.\n", state);
3364 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3365 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3366 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3368 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3369 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3371 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3372 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3373 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3375 hr = IMFClockStateSink_OnClockStart(statesink, 0, 1);
3376 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3378 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3379 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3380 ok(time == systime + 1, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3381 wine_dbgstr_longlong(systime));
3383 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3384 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3386 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3387 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3388 ok(time == 3, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3390 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3391 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3393 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3394 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3395 ok(time == systime - 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3396 wine_dbgstr_longlong(systime));
3398 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3399 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3401 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3402 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3403 ok(time == -2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3404 wine_dbgstr_longlong(systime));
3406 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3407 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3409 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3410 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3411 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3413 /* Increased rate. */
3414 hr = IMFClockStateSink_OnClockSetRate(statesink, 0, 2.0f);
3415 ok(hr == S_OK, "Failed to set rate, hr %#x.\n", hr);
3417 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3418 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3420 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3421 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3422 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3423 wine_dbgstr_longlong(2 * systime));
3425 hr = IMFClockStateSink_OnClockStart(statesink, 0, 10);
3426 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3428 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3429 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3430 ok(time == 2 * systime + 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3431 wine_dbgstr_longlong(2 * systime));
3433 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3434 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3436 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3437 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3438 ok(time == 10 + 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3439 wine_dbgstr_longlong(systime));
3441 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3442 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3444 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3445 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3446 ok(time == 2 * systime + 14 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3447 wine_dbgstr_longlong(systime));
3449 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3450 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3452 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3453 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3454 ok(time == 4, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3455 wine_dbgstr_longlong(systime));
3457 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3458 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3460 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3461 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3462 ok(time == 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time), wine_dbgstr_longlong(systime));
3464 hr = IMFClockStateSink_OnClockStart(statesink, 10, 0);
3465 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3467 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3468 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3469 ok(time == 2 * systime - 2 * 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3470 wine_dbgstr_longlong(2 * systime));
3472 hr = IMFClockStateSink_OnClockStop(statesink, 123);
3473 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3475 hr = IMFClockStateSink_OnClockStart(statesink, 10, 20);
3476 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3478 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3479 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3480 ok(time == 2 * systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3481 wine_dbgstr_longlong(2 * systime));
3483 hr = IMFClockStateSink_OnClockPause(statesink, 2);
3484 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3486 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3487 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3488 ok(time == 2 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3489 wine_dbgstr_longlong(systime));
3491 hr = IMFClockStateSink_OnClockRestart(statesink, 5);
3492 ok(hr == S_OK, "Failed to restart source, hr %#x.\n", hr);
3494 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3495 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3496 ok(time == 2 * systime + 4 - 5 * 2, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3497 wine_dbgstr_longlong(systime));
3499 hr = IMFClockStateSink_OnClockPause(statesink, 0);
3500 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3502 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3503 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3504 ok(time == -6, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3505 wine_dbgstr_longlong(systime));
3507 IMFClockStateSink_Release(statesink);
3508 IMFPresentationTimeSource_Release(time_source);
3510 /* PRESENTATION_CURRENT_POSITION */
3511 hr = MFCreateSystemTimeSource(&time_source);
3512 ok(hr == S_OK, "Failed to create time source, hr %#x.\n", hr);
3514 hr = IMFPresentationTimeSource_QueryInterface(time_source, &IID_IMFClockStateSink, (void **)&statesink);
3515 ok(hr == S_OK, "Failed to get sink interface, hr %#x.\n", hr);
3517 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3518 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3519 ok(!time && systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3520 wine_dbgstr_longlong(systime));
3522 /* INVALID -> RUNNING */
3523 hr = IMFClockStateSink_OnClockStart(statesink, 10, PRESENTATION_CURRENT_POSITION);
3524 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3526 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3527 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3528 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3529 wine_dbgstr_longlong(systime));
3531 /* RUNNING -> RUNNING */
3532 hr = IMFClockStateSink_OnClockStart(statesink, 20, PRESENTATION_CURRENT_POSITION);
3533 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3535 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3536 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3537 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3538 wine_dbgstr_longlong(systime));
3540 hr = IMFClockStateSink_OnClockStart(statesink, 0, PRESENTATION_CURRENT_POSITION);
3541 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3543 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3544 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3545 ok(time == systime - 10, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3546 wine_dbgstr_longlong(systime));
3548 hr = IMFClockStateSink_OnClockStart(statesink, 0, 0);
3549 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3551 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3552 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3553 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3554 wine_dbgstr_longlong(systime));
3556 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3557 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3559 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3560 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3561 ok(time == systime, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3562 wine_dbgstr_longlong(systime));
3564 /* STOPPED -> RUNNING */
3565 hr = IMFClockStateSink_OnClockStop(statesink, 567);
3566 ok(hr == S_OK, "Failed to stop source, hr %#x.\n", hr);
3568 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3569 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3570 ok(!time && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3571 wine_dbgstr_longlong(systime));
3573 hr = IMFClockStateSink_OnClockStart(statesink, 30, PRESENTATION_CURRENT_POSITION);
3574 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3576 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3577 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3578 ok(time == systime - 30, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3579 wine_dbgstr_longlong(systime));
3581 /* PAUSED -> RUNNING */
3582 hr = IMFClockStateSink_OnClockPause(statesink, 8);
3583 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3585 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3586 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3587 ok(time == (-30 + 8) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3588 wine_dbgstr_longlong(systime));
3590 hr = IMFClockStateSink_OnClockStart(statesink, 40, PRESENTATION_CURRENT_POSITION);
3591 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3593 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3594 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3595 ok(time == systime + (-30 + 8 - 40), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3596 wine_dbgstr_longlong(systime));
3598 hr = IMFClockStateSink_OnClockPause(statesink, 7);
3599 ok(hr == S_OK, "Failed to pause source, hr %#x.\n", hr);
3601 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3602 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3603 ok(time == (-30 + 8 - 40 + 7) && systime != 0, "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3604 wine_dbgstr_longlong(systime));
3606 hr = IMFClockStateSink_OnClockStart(statesink, 50, 7);
3607 ok(hr == S_OK, "Failed to start source, hr %#x.\n", hr);
3609 hr = IMFPresentationTimeSource_GetCorrelatedTime(time_source, 0, &time, &systime);
3610 ok(hr == S_OK, "Failed to get time %#x.\n", hr);
3611 ok(time == systime + (-50 + 7), "Unexpected time stamp %s, %s.\n", wine_dbgstr_longlong(time),
3612 wine_dbgstr_longlong(systime));
3614 IMFClockStateSink_Release(statesink);
3615 IMFPresentationTimeSource_Release(time_source);
3618 static void test_MFInvokeCallback(void)
3620 struct test_callback callback;
3621 IMFAsyncResult *result;
3622 MFASYNCRESULT *data;
3623 ULONG refcount;
3624 HRESULT hr;
3625 DWORD ret;
3627 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
3628 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
3630 init_test_callback(&callback);
3632 hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result);
3633 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
3635 data = (MFASYNCRESULT *)result;
3636 data->hEvent = CreateEventA(NULL, FALSE, FALSE, NULL);
3637 ok(data->hEvent != NULL, "Failed to create event.\n");
3639 hr = MFInvokeCallback(result);
3640 ok(hr == S_OK, "Failed to invoke, hr %#x.\n", hr);
3642 ret = WaitForSingleObject(data->hEvent, 100);
3643 ok(ret == WAIT_TIMEOUT, "Expected timeout, ret %#x.\n", ret);
3645 refcount = IMFAsyncResult_Release(result);
3646 ok(!refcount, "Unexpected refcount %u.\n", refcount);
3648 hr = MFShutdown();
3649 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
3652 static void test_stream_descriptor(void)
3654 IMFMediaType *media_types[2], *media_type, *media_type2, *media_type3;
3655 IMFMediaTypeHandler *type_handler;
3656 IMFStreamDescriptor *stream_desc;
3657 GUID major_type;
3658 DWORD id, count;
3659 unsigned int i;
3660 HRESULT hr;
3662 hr = MFCreateStreamDescriptor(123, 0, NULL, &stream_desc);
3663 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3665 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3667 hr = MFCreateMediaType(&media_types[i]);
3668 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3671 hr = MFCreateStreamDescriptor(123, 0, media_types, &stream_desc);
3672 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
3674 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3675 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3677 hr = IMFStreamDescriptor_GetStreamIdentifier(stream_desc, &id);
3678 ok(hr == S_OK, "Failed to get descriptor id, hr %#x.\n", hr);
3679 ok(id == 123, "Unexpected id %#x.\n", id);
3681 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3682 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3684 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3685 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3686 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3688 hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &media_type);
3689 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
3691 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3692 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3694 for (i = 0; i < ARRAY_SIZE(media_types); ++i)
3696 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, i, &media_type);
3697 ok(hr == S_OK, "Failed to get media type, hr %#x.\n", hr);
3698 ok(media_type == media_types[i], "Unexpected object.\n");
3700 if (SUCCEEDED(hr))
3701 IMFMediaType_Release(media_type);
3704 hr = IMFMediaTypeHandler_GetMediaTypeByIndex(type_handler, 2, &media_type);
3705 ok(hr == MF_E_NO_MORE_TYPES, "Unexpected hr %#x.\n", hr);
3707 /* IsMediaTypeSupported() */
3709 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, NULL);
3710 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3712 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, NULL, &media_type2);
3713 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3715 hr = MFCreateMediaType(&media_type);
3716 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3718 hr = MFCreateMediaType(&media_type3);
3719 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
3721 media_type2 = (void *)0xdeadbeef;
3722 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3723 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3724 ok(!media_type2, "Unexpected pointer.\n");
3726 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, NULL);
3727 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
3729 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type);
3730 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3732 media_type2 = (void *)0xdeadbeef;
3733 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3734 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3735 ok(!media_type2, "Unexpected pointer.\n");
3737 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3738 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
3740 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3741 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3743 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3744 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
3745 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type.\n");
3747 /* Mismatching major types. */
3748 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3749 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
3751 media_type2 = (void *)0xdeadbeef;
3752 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3753 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3754 ok(!media_type2, "Unexpected pointer.\n");
3756 /* Subtype missing. */
3757 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3758 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3760 hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3761 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3763 media_type2 = (void *)0xdeadbeef;
3764 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3765 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3766 ok(!media_type2, "Unexpected pointer.\n");
3768 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3769 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3771 media_type2 = (void *)0xdeadbeef;
3772 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3773 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3774 ok(!media_type2, "Unexpected pointer.\n");
3776 /* Mismatching subtype. */
3777 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3778 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
3780 media_type2 = (void *)0xdeadbeef;
3781 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3782 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3783 ok(!media_type2, "Unexpected pointer.\n");
3785 hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &count);
3786 ok(hr == S_OK, "Failed to get type count, hr %#x.\n", hr);
3787 ok(count == ARRAY_SIZE(media_types), "Unexpected type count.\n");
3789 IMFMediaTypeHandler_Release(type_handler);
3790 IMFStreamDescriptor_Release(stream_desc);
3792 /* IsMediaTypeSupported() for unset current type. */
3793 hr = MFCreateStreamDescriptor(123, ARRAY_SIZE(media_types), media_types, &stream_desc);
3794 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3796 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3797 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3799 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, NULL);
3800 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3802 /* Initialize one from initial type set. */
3803 hr = IMFMediaType_CopyAllItems(media_type3, (IMFAttributes *)media_types[0]);
3804 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3806 media_type2 = (void *)0xdeadbeef;
3807 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3808 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3809 ok(!media_type2, "Unexpected pointer.\n");
3811 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
3812 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3814 media_type2 = (void *)0xdeadbeef;
3815 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3816 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
3817 ok(!media_type2, "Unexpected pointer.\n");
3819 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFAudioFormat_MP3);
3820 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3822 media_type2 = (void *)0xdeadbeef;
3823 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3825 ok(!media_type2, "Unexpected pointer.\n");
3827 /* Now set current type that's not compatible. */
3828 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3829 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3831 hr = IMFMediaType_SetGUID(media_type3, &MF_MT_SUBTYPE, &MFVideoFormat_RGB8);
3832 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3834 hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, media_type3);
3835 ok(hr == S_OK, "Failed to set current type, hr %#x.\n", hr);
3837 media_type2 = (void *)0xdeadbeef;
3838 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type3, &media_type2);
3839 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3840 ok(!media_type2, "Unexpected pointer.\n");
3842 hr = IMFMediaType_CopyAllItems(media_types[0], (IMFAttributes *)media_type);
3843 ok(hr == S_OK, "Failed to copy attributes, hr %#x.\n", hr);
3845 media_type2 = (void *)0xdeadbeef;
3846 hr = IMFMediaTypeHandler_IsMediaTypeSupported(type_handler, media_type, &media_type2);
3847 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3848 ok(!media_type2, "Unexpected pointer.\n");
3850 IMFMediaType_Release(media_type);
3851 IMFMediaType_Release(media_type3);
3853 IMFMediaTypeHandler_Release(type_handler);
3855 IMFStreamDescriptor_Release(stream_desc);
3857 /* Major type is returned for first entry. */
3858 hr = MFCreateMediaType(&media_types[0]);
3859 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3860 hr = MFCreateMediaType(&media_types[1]);
3861 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3863 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3864 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3865 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3866 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3868 hr = MFCreateStreamDescriptor(0, 2, media_types, &stream_desc);
3869 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3871 hr = IMFStreamDescriptor_GetMediaTypeHandler(stream_desc, &type_handler);
3872 ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
3874 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3875 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3876 ok(IsEqualGUID(&major_type, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3878 hr = IMFMediaType_SetGUID(media_types[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
3879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3880 hr = IMFMediaType_SetGUID(media_types[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
3881 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3883 hr = IMFMediaTypeHandler_GetMajorType(type_handler, &major_type);
3884 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
3885 ok(IsEqualGUID(&major_type, &MFMediaType_Video), "Unexpected major type %s.\n", wine_dbgstr_guid(&major_type));
3887 IMFMediaType_Release(media_types[0]);
3888 IMFMediaType_Release(media_types[1]);
3890 IMFMediaTypeHandler_Release(type_handler);
3891 IMFStreamDescriptor_Release(stream_desc);
3894 static void test_MFCalculateImageSize(void)
3896 static const struct image_size_test
3898 const GUID *subtype;
3899 UINT32 width;
3900 UINT32 height;
3901 UINT32 size;
3902 UINT32 plane_size; /* Matches image size when 0. */
3904 image_size_tests[] =
3906 { &MFVideoFormat_RGB8, 3, 5, 20 },
3907 { &MFVideoFormat_RGB8, 1, 1, 4 },
3908 { &MFVideoFormat_RGB555, 3, 5, 40 },
3909 { &MFVideoFormat_RGB555, 1, 1, 4 },
3910 { &MFVideoFormat_RGB565, 3, 5, 40 },
3911 { &MFVideoFormat_RGB565, 1, 1, 4 },
3912 { &MFVideoFormat_RGB24, 3, 5, 60 },
3913 { &MFVideoFormat_RGB24, 1, 1, 4 },
3914 { &MFVideoFormat_RGB32, 3, 5, 60 },
3915 { &MFVideoFormat_RGB32, 1, 1, 4 },
3916 { &MFVideoFormat_ARGB32, 3, 5, 60 },
3917 { &MFVideoFormat_ARGB32, 1, 1, 4 },
3918 { &MFVideoFormat_A2R10G10B10, 3, 5, 60 },
3919 { &MFVideoFormat_A2R10G10B10, 1, 1, 4 },
3920 { &MFVideoFormat_A16B16G16R16F, 3, 5, 120 },
3921 { &MFVideoFormat_A16B16G16R16F, 1, 1, 8 },
3923 /* YUV */
3924 { &MFVideoFormat_NV12, 1, 3, 9, 4 },
3925 { &MFVideoFormat_NV12, 1, 2, 6, 3 },
3926 { &MFVideoFormat_NV12, 2, 2, 6, 6 },
3927 { &MFVideoFormat_NV12, 3, 2, 12, 9 },
3928 { &MFVideoFormat_NV12, 4, 2, 12 },
3929 { &MFVideoFormat_NV12, 320, 240, 115200 },
3930 { &MFVideoFormat_AYUV, 1, 1, 4 },
3931 { &MFVideoFormat_AYUV, 2, 1, 8 },
3932 { &MFVideoFormat_AYUV, 1, 2, 8 },
3933 { &MFVideoFormat_AYUV, 4, 3, 48 },
3934 { &MFVideoFormat_AYUV, 320, 240, 307200 },
3935 { &MFVideoFormat_IMC1, 1, 1, 4 },
3936 { &MFVideoFormat_IMC1, 2, 1, 4 },
3937 { &MFVideoFormat_IMC1, 1, 2, 8 },
3938 { &MFVideoFormat_IMC1, 4, 3, 24 },
3939 { &MFVideoFormat_IMC1, 320, 240, 153600 },
3940 { &MFVideoFormat_IMC3, 1, 1, 4 },
3941 { &MFVideoFormat_IMC3, 2, 1, 4 },
3942 { &MFVideoFormat_IMC3, 1, 2, 8 },
3943 { &MFVideoFormat_IMC3, 4, 3, 24 },
3944 { &MFVideoFormat_IMC3, 320, 240, 153600 },
3945 { &MFVideoFormat_IMC2, 1, 3, 9, 4 },
3946 { &MFVideoFormat_IMC2, 1, 2, 6, 3 },
3947 { &MFVideoFormat_IMC2, 2, 2, 6, 6 },
3948 { &MFVideoFormat_IMC2, 3, 2, 12, 9 },
3949 { &MFVideoFormat_IMC2, 4, 2, 12 },
3950 { &MFVideoFormat_IMC2, 320, 240, 115200 },
3951 { &MFVideoFormat_IMC4, 1, 3, 9, 4 },
3952 { &MFVideoFormat_IMC4, 1, 2, 6, 3 },
3953 { &MFVideoFormat_IMC4, 2, 2, 6, 6 },
3954 { &MFVideoFormat_IMC4, 3, 2, 12, 9 },
3955 { &MFVideoFormat_IMC4, 4, 2, 12 },
3956 { &MFVideoFormat_IMC4, 320, 240, 115200 },
3957 { &MFVideoFormat_YV12, 1, 1, 3, 1 },
3958 { &MFVideoFormat_YV12, 2, 1, 3 },
3959 { &MFVideoFormat_YV12, 1, 2, 6, 3 },
3960 { &MFVideoFormat_YV12, 4, 3, 18 },
3961 { &MFVideoFormat_YV12, 320, 240, 115200 },
3963 { &MFVideoFormat_I420, 1, 1, 3, 1 },
3964 { &MFVideoFormat_I420, 2, 1, 3 },
3965 { &MFVideoFormat_I420, 1, 2, 6, 3 },
3966 { &MFVideoFormat_I420, 4, 3, 18 },
3967 { &MFVideoFormat_I420, 320, 240, 115200 },
3969 { &MFVideoFormat_YUY2, 2, 1, 4 },
3970 { &MFVideoFormat_YUY2, 4, 3, 24 },
3971 { &MFVideoFormat_YUY2, 128, 128, 32768 },
3972 { &MFVideoFormat_YUY2, 320, 240, 153600 },
3974 { &MFVideoFormat_UYVY, 2, 1, 4 },
3975 { &MFVideoFormat_UYVY, 4, 3, 24 },
3976 { &MFVideoFormat_UYVY, 128, 128, 32768 },
3977 { &MFVideoFormat_UYVY, 320, 240, 153600 },
3979 unsigned int i;
3980 UINT32 size;
3981 HRESULT hr;
3983 if (!pMFGetPlaneSize)
3984 win_skip("MFGetPlaneSize() is not available.\n");
3986 size = 1;
3987 hr = MFCalculateImageSize(&IID_IUnknown, 1, 1, &size);
3988 ok(hr == E_INVALIDARG || broken(hr == S_OK) /* Vista */, "Unexpected hr %#x.\n", hr);
3989 ok(size == 0, "Unexpected size %u.\n", size);
3991 for (i = 0; i < ARRAY_SIZE(image_size_tests); ++i)
3993 const struct image_size_test *ptr = &image_size_tests[i];
3995 /* Those are supported since Win10. */
3996 BOOL is_broken = IsEqualGUID(ptr->subtype, &MFVideoFormat_A16B16G16R16F) ||
3997 IsEqualGUID(ptr->subtype, &MFVideoFormat_A2R10G10B10);
3999 hr = MFCalculateImageSize(ptr->subtype, ptr->width, ptr->height, &size);
4000 ok(hr == S_OK || (is_broken && hr == E_INVALIDARG), "%u: failed to calculate image size, hr %#x.\n", i, hr);
4001 ok(size == ptr->size, "%u: unexpected image size %u, expected %u. Size %u x %u, format %s.\n", i, size, ptr->size,
4002 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->subtype->Data1, 4));
4004 if (pMFGetPlaneSize)
4006 unsigned int plane_size = ptr->plane_size ? ptr->plane_size : ptr->size;
4008 hr = pMFGetPlaneSize(ptr->subtype->Data1, ptr->width, ptr->height, &size);
4009 ok(hr == S_OK, "%u: failed to get plane size, hr %#x.\n", i, hr);
4010 ok(size == plane_size, "%u: unexpected plane size %u, expected %u.\n", i, size, plane_size);
4015 static void test_MFCompareFullToPartialMediaType(void)
4017 IMFMediaType *full_type, *partial_type;
4018 HRESULT hr;
4019 BOOL ret;
4021 hr = MFCreateMediaType(&full_type);
4022 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4024 hr = MFCreateMediaType(&partial_type);
4025 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4027 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4028 ok(!ret, "Unexpected result %d.\n", ret);
4030 hr = IMFMediaType_SetGUID(full_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4031 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4033 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4034 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4036 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4037 ok(ret, "Unexpected result %d.\n", ret);
4039 hr = IMFMediaType_SetGUID(full_type, &MF_MT_SUBTYPE, &MFMediaType_Audio);
4040 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4042 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4043 ok(ret, "Unexpected result %d.\n", ret);
4045 hr = IMFMediaType_SetGUID(partial_type, &MF_MT_SUBTYPE, &MFMediaType_Video);
4046 ok(hr == S_OK, "Failed to set major type, hr %#x.\n", hr);
4048 ret = MFCompareFullToPartialMediaType(full_type, partial_type);
4049 ok(!ret, "Unexpected result %d.\n", ret);
4051 IMFMediaType_Release(full_type);
4052 IMFMediaType_Release(partial_type);
4055 static void test_attributes_serialization(void)
4057 static const UINT8 blob[] = {1,2,3};
4058 IMFAttributes *attributes, *dest;
4059 UINT32 size, count, value32;
4060 double value_dbl;
4061 UINT64 value64;
4062 UINT8 *buffer;
4063 IUnknown *obj;
4064 HRESULT hr;
4065 WCHAR *str;
4066 GUID guid;
4068 hr = MFCreateAttributes(&attributes, 0);
4069 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4071 hr = MFCreateAttributes(&dest, 0);
4072 ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
4074 hr = MFGetAttributesAsBlobSize(attributes, &size);
4075 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4076 ok(size == 8, "Got size %u.\n", size);
4078 buffer = heap_alloc(size);
4080 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4081 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4083 hr = MFGetAttributesAsBlob(attributes, buffer, size - 1);
4084 ok(hr == MF_E_BUFFERTOOSMALL, "Unexpected hr %#x.\n", hr);
4086 hr = MFInitAttributesFromBlob(dest, buffer, size - 1);
4087 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4089 hr = IMFAttributes_SetUINT32(dest, &MF_MT_MAJOR_TYPE, 1);
4090 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4092 hr = MFInitAttributesFromBlob(dest, buffer, size);
4093 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4095 /* Previous items are cleared. */
4096 hr = IMFAttributes_GetCount(dest, &count);
4097 ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
4098 ok(count == 0, "Unexpected count %u.\n", count);
4100 heap_free(buffer);
4102 /* Set some attributes of various types. */
4103 IMFAttributes_SetUINT32(attributes, &MF_MT_MAJOR_TYPE, 456);
4104 IMFAttributes_SetUINT64(attributes, &MF_MT_SUBTYPE, 123);
4105 IMFAttributes_SetDouble(attributes, &IID_IUnknown, 0.5);
4106 IMFAttributes_SetUnknown(attributes, &IID_IMFAttributes, (IUnknown *)attributes);
4107 IMFAttributes_SetGUID(attributes, &GUID_NULL, &IID_IUnknown);
4108 IMFAttributes_SetString(attributes, &DUMMY_CLSID, L"Text");
4109 IMFAttributes_SetBlob(attributes, &DUMMY_GUID1, blob, sizeof(blob));
4111 hr = MFGetAttributesAsBlobSize(attributes, &size);
4112 ok(hr == S_OK, "Failed to get blob size, hr %#x.\n", hr);
4113 ok(size > 8, "Got unexpected size %u.\n", size);
4115 buffer = heap_alloc(size);
4116 hr = MFGetAttributesAsBlob(attributes, buffer, size);
4117 ok(hr == S_OK, "Failed to serialize, hr %#x.\n", hr);
4118 hr = MFInitAttributesFromBlob(dest, buffer, size);
4119 ok(hr == S_OK, "Failed to deserialize, hr %#x.\n", hr);
4120 heap_free(buffer);
4122 hr = IMFAttributes_GetUINT32(dest, &MF_MT_MAJOR_TYPE, &value32);
4123 ok(hr == S_OK, "Failed to get get uint32 value, hr %#x.\n", hr);
4124 ok(value32 == 456, "Unexpected value %u.\n", value32);
4125 hr = IMFAttributes_GetUINT64(dest, &MF_MT_SUBTYPE, &value64);
4126 ok(hr == S_OK, "Failed to get get uint64 value, hr %#x.\n", hr);
4127 ok(value64 == 123, "Unexpected value.\n");
4128 hr = IMFAttributes_GetDouble(dest, &IID_IUnknown, &value_dbl);
4129 ok(hr == S_OK, "Failed to get get double value, hr %#x.\n", hr);
4130 ok(value_dbl == 0.5, "Unexpected value.\n");
4131 hr = IMFAttributes_GetUnknown(dest, &IID_IMFAttributes, &IID_IUnknown, (void **)&obj);
4132 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4133 hr = IMFAttributes_GetGUID(dest, &GUID_NULL, &guid);
4134 ok(hr == S_OK, "Failed to get guid value, hr %#x.\n", hr);
4135 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected guid.\n");
4136 hr = IMFAttributes_GetAllocatedString(dest, &DUMMY_CLSID, &str, &size);
4137 ok(hr == S_OK, "Failed to get string value, hr %#x.\n", hr);
4138 ok(!lstrcmpW(str, L"Text"), "Unexpected string.\n");
4139 CoTaskMemFree(str);
4140 hr = IMFAttributes_GetAllocatedBlob(dest, &DUMMY_GUID1, &buffer, &size);
4141 ok(hr == S_OK, "Failed to get blob value, hr %#x.\n", hr);
4142 ok(!memcmp(buffer, blob, sizeof(blob)), "Unexpected blob.\n");
4143 CoTaskMemFree(buffer);
4145 IMFAttributes_Release(attributes);
4146 IMFAttributes_Release(dest);
4149 static void test_wrapped_media_type(void)
4151 IMFMediaType *mediatype, *mediatype2;
4152 UINT32 count, type;
4153 HRESULT hr;
4154 GUID guid;
4156 hr = MFCreateMediaType(&mediatype);
4157 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4159 hr = MFUnwrapMediaType(mediatype, &mediatype2);
4160 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4162 hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1);
4163 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4164 hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2);
4165 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4167 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4168 ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr);
4170 hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2);
4171 ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr);
4173 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid);
4174 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4175 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n");
4177 hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid);
4178 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
4179 ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n");
4181 hr = IMFMediaType_GetCount(mediatype2, &count);
4182 ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr);
4183 ok(count == 3, "Unexpected count %u.\n", count);
4185 hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type);
4186 ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr);
4187 ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n");
4189 IMFMediaType_Release(mediatype);
4191 hr = MFUnwrapMediaType(mediatype2, &mediatype);
4192 ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr);
4194 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid);
4195 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
4196 ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n");
4198 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
4199 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4201 IMFMediaType_Release(mediatype);
4202 IMFMediaType_Release(mediatype2);
4205 static void test_MFCreateWaveFormatExFromMFMediaType(void)
4207 WAVEFORMATEXTENSIBLE *format_ext;
4208 IMFMediaType *mediatype;
4209 WAVEFORMATEX *format;
4210 UINT32 size;
4211 HRESULT hr;
4213 hr = MFCreateMediaType(&mediatype);
4214 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
4216 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4217 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4219 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
4220 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4222 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4223 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
4225 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFMediaType_Video);
4226 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4228 /* Audio/PCM */
4229 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
4230 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4231 hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
4232 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
4234 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_Normal);
4235 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4236 ok(format != NULL, "Expected format structure.\n");
4237 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4238 ok(format->wFormatTag == WAVE_FORMAT_PCM, "Unexpected tag.\n");
4239 ok(format->nChannels == 0, "Unexpected number of channels, %u.\n", format->nChannels);
4240 ok(format->nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format->nSamplesPerSec);
4241 ok(format->nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n", format->nAvgBytesPerSec);
4242 ok(format->nBlockAlign == 0, "Unexpected alignment, %u.\n", format->nBlockAlign);
4243 ok(format->wBitsPerSample == 0, "Unexpected sample size, %u.\n", format->wBitsPerSample);
4244 ok(format->cbSize == 0, "Unexpected size field, %u.\n", format->cbSize);
4245 CoTaskMemFree(format);
4247 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format_ext, &size,
4248 MFWaveFormatExConvertFlag_ForceExtensible);
4249 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4250 ok(format_ext != NULL, "Expected format structure.\n");
4251 ok(size == sizeof(*format_ext), "Unexpected size %u.\n", size);
4252 ok(format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "Unexpected tag.\n");
4253 ok(format_ext->Format.nChannels == 0, "Unexpected number of channels, %u.\n", format_ext->Format.nChannels);
4254 ok(format_ext->Format.nSamplesPerSec == 0, "Unexpected sample rate, %u.\n", format_ext->Format.nSamplesPerSec);
4255 ok(format_ext->Format.nAvgBytesPerSec == 0, "Unexpected average data rate rate, %u.\n",
4256 format_ext->Format.nAvgBytesPerSec);
4257 ok(format_ext->Format.nBlockAlign == 0, "Unexpected alignment, %u.\n", format_ext->Format.nBlockAlign);
4258 ok(format_ext->Format.wBitsPerSample == 0, "Unexpected sample size, %u.\n", format_ext->Format.wBitsPerSample);
4259 ok(format_ext->Format.cbSize == sizeof(*format_ext) - sizeof(format_ext->Format), "Unexpected size field, %u.\n",
4260 format_ext->Format.cbSize);
4261 CoTaskMemFree(format_ext);
4263 hr = MFCreateWaveFormatExFromMFMediaType(mediatype, &format, &size, MFWaveFormatExConvertFlag_ForceExtensible + 1);
4264 ok(hr == S_OK, "Failed to create format, hr %#x.\n", hr);
4265 ok(size == sizeof(*format), "Unexpected size %u.\n", size);
4266 CoTaskMemFree(format);
4268 IMFMediaType_Release(mediatype);
4271 static HRESULT WINAPI test_create_file_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
4273 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
4274 IMFByteStream *stream;
4275 IUnknown *object;
4276 HRESULT hr;
4278 ok(!!result, "Unexpected result object.\n");
4280 ok((IUnknown *)iface == IMFAsyncResult_GetStateNoAddRef(result), "Unexpected result state.\n");
4282 hr = IMFAsyncResult_GetObject(result, &object);
4283 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
4285 hr = MFEndCreateFile(result, &stream);
4286 ok(hr == S_OK, "Failed to get file stream, hr %#x.\n", hr);
4287 IMFByteStream_Release(stream);
4289 SetEvent(callback->event);
4291 return S_OK;
4294 static const IMFAsyncCallbackVtbl test_create_file_callback_vtbl =
4296 testcallback_QueryInterface,
4297 testcallback_AddRef,
4298 testcallback_Release,
4299 testcallback_GetParameters,
4300 test_create_file_callback_Invoke,
4303 static void test_async_create_file(void)
4305 struct test_callback callback = { { &test_create_file_callback_vtbl } };
4306 WCHAR pathW[MAX_PATH], fileW[MAX_PATH];
4307 IUnknown *cancel_cookie;
4308 HRESULT hr;
4309 BOOL ret;
4311 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
4312 ok(hr == S_OK, "Fail to start up, hr %#x.\n", hr);
4314 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
4316 GetTempPathW(ARRAY_SIZE(pathW), pathW);
4317 GetTempFileNameW(pathW, NULL, 0, fileW);
4319 hr = MFBeginCreateFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, fileW,
4320 &callback.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface, &cancel_cookie);
4321 ok(hr == S_OK, "Async create request failed, hr %#x.\n", hr);
4322 ok(cancel_cookie != NULL, "Unexpected cancellation object.\n");
4324 WaitForSingleObject(callback.event, INFINITE);
4326 IUnknown_Release(cancel_cookie);
4328 CloseHandle(callback.event);
4330 hr = MFShutdown();
4331 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
4333 ret = DeleteFileW(fileW);
4334 ok(ret, "Failed to delete test file.\n");
4337 struct activate_object
4339 IMFActivate IMFActivate_iface;
4340 LONG refcount;
4343 static HRESULT WINAPI activate_object_QueryInterface(IMFActivate *iface, REFIID riid, void **obj)
4345 if (IsEqualIID(riid, &IID_IMFActivate) ||
4346 IsEqualIID(riid, &IID_IMFAttributes) ||
4347 IsEqualIID(riid, &IID_IUnknown))
4349 *obj = iface;
4350 IMFActivate_AddRef(iface);
4351 return S_OK;
4354 *obj = NULL;
4355 return E_NOINTERFACE;
4358 static ULONG WINAPI activate_object_AddRef(IMFActivate *iface)
4360 return 2;
4363 static ULONG WINAPI activate_object_Release(IMFActivate *iface)
4365 return 1;
4368 static HRESULT WINAPI activate_object_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value)
4370 return E_NOTIMPL;
4373 static HRESULT WINAPI activate_object_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type)
4375 return E_NOTIMPL;
4378 static HRESULT WINAPI activate_object_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, BOOL *result)
4380 return E_NOTIMPL;
4383 static HRESULT WINAPI activate_object_Compare(IMFActivate *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type,
4384 BOOL *result)
4386 return E_NOTIMPL;
4389 static HRESULT WINAPI activate_object_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value)
4391 return E_NOTIMPL;
4394 static HRESULT WINAPI activate_object_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value)
4396 return E_NOTIMPL;
4399 static HRESULT WINAPI activate_object_GetDouble(IMFActivate *iface, REFGUID key, double *value)
4401 return E_NOTIMPL;
4404 static HRESULT WINAPI activate_object_GetGUID(IMFActivate *iface, REFGUID key, GUID *value)
4406 return E_NOTIMPL;
4409 static HRESULT WINAPI activate_object_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length)
4411 return E_NOTIMPL;
4414 static HRESULT WINAPI activate_object_GetString(IMFActivate *iface, REFGUID key, WCHAR *value,
4415 UINT32 size, UINT32 *length)
4417 return E_NOTIMPL;
4420 static HRESULT WINAPI activate_object_GetAllocatedString(IMFActivate *iface, REFGUID key,
4421 WCHAR **value, UINT32 *length)
4423 return E_NOTIMPL;
4426 static HRESULT WINAPI activate_object_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size)
4428 return E_NOTIMPL;
4431 static HRESULT WINAPI activate_object_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf,
4432 UINT32 bufsize, UINT32 *blobsize)
4434 return E_NOTIMPL;
4437 static HRESULT WINAPI activate_object_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size)
4439 return E_NOTIMPL;
4442 static HRESULT WINAPI activate_object_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **ppv)
4444 return E_NOTIMPL;
4447 static HRESULT WINAPI activate_object_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value)
4449 return E_NOTIMPL;
4452 static HRESULT WINAPI activate_object_DeleteItem(IMFActivate *iface, REFGUID key)
4454 return E_NOTIMPL;
4457 static HRESULT WINAPI activate_object_DeleteAllItems(IMFActivate *iface)
4459 return E_NOTIMPL;
4462 static HRESULT WINAPI activate_object_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value)
4464 return E_NOTIMPL;
4467 static HRESULT WINAPI activate_object_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value)
4469 return E_NOTIMPL;
4472 static HRESULT WINAPI activate_object_SetDouble(IMFActivate *iface, REFGUID key, double value)
4474 return E_NOTIMPL;
4477 static HRESULT WINAPI activate_object_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value)
4479 return E_NOTIMPL;
4482 static HRESULT WINAPI activate_object_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value)
4484 return E_NOTIMPL;
4487 static HRESULT WINAPI activate_object_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size)
4489 return E_NOTIMPL;
4492 static HRESULT WINAPI activate_object_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown)
4494 return E_NOTIMPL;
4497 static HRESULT WINAPI activate_object_LockStore(IMFActivate *iface)
4499 return E_NOTIMPL;
4502 static HRESULT WINAPI activate_object_UnlockStore(IMFActivate *iface)
4504 return E_NOTIMPL;
4507 static HRESULT WINAPI activate_object_GetCount(IMFActivate *iface, UINT32 *count)
4509 return E_NOTIMPL;
4512 static HRESULT WINAPI activate_object_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, PROPVARIANT *value)
4514 return E_NOTIMPL;
4517 static HRESULT WINAPI activate_object_CopyAllItems(IMFActivate *iface, IMFAttributes *dest)
4519 return E_NOTIMPL;
4522 static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID riid, void **obj)
4524 return E_NOTIMPL;
4527 static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
4529 return E_NOTIMPL;
4532 static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
4534 return E_NOTIMPL;
4537 static const IMFActivateVtbl activate_object_vtbl =
4539 activate_object_QueryInterface,
4540 activate_object_AddRef,
4541 activate_object_Release,
4542 activate_object_GetItem,
4543 activate_object_GetItemType,
4544 activate_object_CompareItem,
4545 activate_object_Compare,
4546 activate_object_GetUINT32,
4547 activate_object_GetUINT64,
4548 activate_object_GetDouble,
4549 activate_object_GetGUID,
4550 activate_object_GetStringLength,
4551 activate_object_GetString,
4552 activate_object_GetAllocatedString,
4553 activate_object_GetBlobSize,
4554 activate_object_GetBlob,
4555 activate_object_GetAllocatedBlob,
4556 activate_object_GetUnknown,
4557 activate_object_SetItem,
4558 activate_object_DeleteItem,
4559 activate_object_DeleteAllItems,
4560 activate_object_SetUINT32,
4561 activate_object_SetUINT64,
4562 activate_object_SetDouble,
4563 activate_object_SetGUID,
4564 activate_object_SetString,
4565 activate_object_SetBlob,
4566 activate_object_SetUnknown,
4567 activate_object_LockStore,
4568 activate_object_UnlockStore,
4569 activate_object_GetCount,
4570 activate_object_GetItemByIndex,
4571 activate_object_CopyAllItems,
4572 activate_object_ActivateObject,
4573 activate_object_ShutdownObject,
4574 activate_object_DetachObject,
4577 static void test_local_handlers(void)
4579 IMFActivate local_activate = { &activate_object_vtbl };
4580 static const WCHAR localW[] = L"local";
4581 HRESULT hr;
4583 if (!pMFRegisterLocalSchemeHandler)
4585 win_skip("Local handlers are not supported.\n");
4586 return;
4589 hr = pMFRegisterLocalSchemeHandler(NULL, NULL);
4590 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4592 hr = pMFRegisterLocalSchemeHandler(localW, NULL);
4593 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4595 hr = pMFRegisterLocalSchemeHandler(NULL, &local_activate);
4596 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4598 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4599 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4601 hr = pMFRegisterLocalSchemeHandler(localW, &local_activate);
4602 ok(hr == S_OK, "Failed to register scheme handler, hr %#x.\n", hr);
4604 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, NULL);
4605 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4607 hr = pMFRegisterLocalByteStreamHandler(NULL, NULL, &local_activate);
4608 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4610 hr = pMFRegisterLocalByteStreamHandler(NULL, localW, &local_activate);
4611 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4613 hr = pMFRegisterLocalByteStreamHandler(localW, NULL, &local_activate);
4614 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4616 hr = pMFRegisterLocalByteStreamHandler(localW, localW, &local_activate);
4617 ok(hr == S_OK, "Failed to register stream handler, hr %#x.\n", hr);
4620 static void test_create_property_store(void)
4622 static const PROPERTYKEY test_pkey = {{0x12345678}, 9};
4623 IPropertyStore *store, *store2;
4624 PROPVARIANT value = {0};
4625 PROPERTYKEY key;
4626 ULONG refcount;
4627 DWORD count;
4628 HRESULT hr;
4630 hr = CreatePropertyStore(NULL);
4631 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4633 hr = CreatePropertyStore(&store);
4634 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4636 hr = CreatePropertyStore(&store2);
4637 ok(hr == S_OK, "Failed to create property store, hr %#x.\n", hr);
4638 ok(store2 != store, "Expected different store objects.\n");
4639 IPropertyStore_Release(store2);
4641 check_interface(store, &IID_IPropertyStoreCache, FALSE);
4642 check_interface(store, &IID_IPersistSerializedPropStorage, FALSE);
4644 hr = IPropertyStore_GetCount(store, NULL);
4645 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4647 count = 0xdeadbeef;
4648 hr = IPropertyStore_GetCount(store, &count);
4649 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4650 ok(!count, "Unexpected count %u.\n", count);
4652 hr = IPropertyStore_Commit(store);
4653 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4655 hr = IPropertyStore_GetAt(store, 0, &key);
4656 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4658 hr = IPropertyStore_GetValue(store, NULL, &value);
4659 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4661 hr = IPropertyStore_GetValue(store, &test_pkey, NULL);
4662 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4664 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4665 ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr);
4667 memset(&value, 0, sizeof(PROPVARIANT));
4668 value.vt = VT_I4;
4669 value.lVal = 0xdeadbeef;
4670 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4671 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4673 if (0)
4675 /* crashes on Windows */
4676 hr = IPropertyStore_SetValue(store, NULL, &value);
4677 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4680 hr = IPropertyStore_GetCount(store, &count);
4681 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4682 ok(count == 1, "Unexpected count %u.\n", count);
4684 hr = IPropertyStore_Commit(store);
4685 ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
4687 hr = IPropertyStore_GetAt(store, 0, &key);
4688 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4689 ok(!memcmp(&key, &test_pkey, sizeof(PROPERTYKEY)), "Keys didn't match.\n");
4691 hr = IPropertyStore_GetAt(store, 1, &key);
4692 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4694 memset(&value, 0xcc, sizeof(PROPVARIANT));
4695 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4696 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4697 ok(value.vt == VT_I4, "Unexpected type %u.\n", value.vt);
4698 ok(value.lVal == 0xdeadbeef, "Unexpected value %#x.\n", value.lVal);
4700 memset(&value, 0, sizeof(PROPVARIANT));
4701 hr = IPropertyStore_SetValue(store, &test_pkey, &value);
4702 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4704 hr = IPropertyStore_GetCount(store, &count);
4705 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4706 ok(count == 1, "Unexpected count %u.\n", count);
4708 memset(&value, 0xcc, sizeof(PROPVARIANT));
4709 hr = IPropertyStore_GetValue(store, &test_pkey, &value);
4710 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4711 ok(value.vt == VT_EMPTY, "Unexpected type %u.\n", value.vt);
4712 ok(!value.lVal, "Unexpected value %#x.\n", value.lVal);
4714 refcount = IPropertyStore_Release(store);
4715 ok(!refcount, "Unexpected refcount %u.\n", refcount);
4718 struct test_thread_param
4720 IMFDXGIDeviceManager *manager;
4721 HANDLE handle;
4722 BOOL lock;
4725 static DWORD WINAPI test_device_manager_thread(void *arg)
4727 struct test_thread_param *param = arg;
4728 ID3D11Device *device;
4729 HRESULT hr;
4731 if (param->lock)
4733 hr = IMFDXGIDeviceManager_LockDevice(param->manager, param->handle, &IID_ID3D11Device,
4734 (void **)&device, FALSE);
4735 if (SUCCEEDED(hr))
4736 ID3D11Device_Release(device);
4738 else
4739 hr = IMFDXGIDeviceManager_UnlockDevice(param->manager, param->handle, FALSE);
4741 return hr;
4744 static void test_dxgi_device_manager(void)
4746 IMFDXGIDeviceManager *manager, *manager2;
4747 ID3D11Device *device, *d3d11_dev, *d3d11_dev2;
4748 struct test_thread_param param;
4749 HANDLE handle1, handle, thread;
4750 UINT token, token2;
4751 IUnknown *unk;
4752 HRESULT hr;
4754 if (!pMFCreateDXGIDeviceManager)
4756 win_skip("MFCreateDXGIDeviceManager not found.\n");
4757 return;
4760 hr = pMFCreateDXGIDeviceManager(NULL, &manager);
4761 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4763 token = 0;
4764 hr = pMFCreateDXGIDeviceManager(&token, NULL);
4765 ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr);
4766 ok(!token, "got wrong token: %u.\n", token);
4768 hr = pMFCreateDXGIDeviceManager(&token, &manager);
4769 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4770 EXPECT_REF(manager, 1);
4771 ok(!!token, "got wrong token: %u.\n", token);
4773 Sleep(50);
4774 token2 = 0;
4775 hr = pMFCreateDXGIDeviceManager(&token2, &manager2);
4776 ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
4777 EXPECT_REF(manager2, 1);
4778 ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token);
4779 ok(manager != manager2, "got wrong pointer: %p.\n", manager2);
4780 EXPECT_REF(manager, 1);
4782 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4783 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4785 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4786 ok(hr == MF_E_DXGI_DEVICE_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
4788 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, 0);
4789 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4791 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_VIDEO_SUPPORT,
4792 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev, NULL, NULL);
4793 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4794 EXPECT_REF(d3d11_dev, 1);
4796 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token - 1);
4797 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4798 EXPECT_REF(d3d11_dev, 1);
4800 hr = IMFDXGIDeviceManager_ResetDevice(manager, NULL, token);
4801 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4803 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4804 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4805 EXPECT_REF(manager, 1);
4806 EXPECT_REF(d3d11_dev, 2);
4808 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)manager2, token);
4809 ok(hr == E_INVALIDARG, "IMFDXGIDeviceManager_ResetDevice should failed: %#x.\n", hr);
4810 EXPECT_REF(manager2, 1);
4811 EXPECT_REF(d3d11_dev, 2);
4813 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev, token);
4814 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4815 EXPECT_REF(manager, 1);
4816 EXPECT_REF(d3d11_dev, 2);
4818 /* GetVideoService() on device change. */
4819 handle = NULL;
4820 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4821 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4822 ok(!!handle, "Unexpected handle value %p.\n", handle);
4824 hr = pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
4825 NULL, 0, D3D11_SDK_VERSION, &d3d11_dev2, NULL, NULL);
4826 ok(hr == S_OK, "D3D11CreateDevice failed: %#x.\n", hr);
4827 EXPECT_REF(d3d11_dev2, 1);
4828 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)d3d11_dev2, token);
4829 ok(hr == S_OK, "IMFDXGIDeviceManager_ResetDevice failed: %#x.\n", hr);
4830 EXPECT_REF(manager, 1);
4831 EXPECT_REF(d3d11_dev2, 2);
4832 EXPECT_REF(d3d11_dev, 1);
4834 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4835 ok(hr == MF_E_DXGI_NEW_VIDEO_DEVICE, "Unexpected hr %#x.\n", hr);
4837 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4838 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4840 handle = NULL;
4841 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4842 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4843 ok(!!handle, "Unexpected handle value %p.\n", handle);
4845 hr = IMFDXGIDeviceManager_GetVideoService(manager, NULL, &IID_ID3D11Device, (void **)&unk);
4846 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4848 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_ID3D11Device, (void **)&unk);
4849 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4850 IUnknown_Release(unk);
4852 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IUnknown, (void **)&unk);
4853 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4854 IUnknown_Release(unk);
4856 hr = IMFDXGIDeviceManager_GetVideoService(manager, handle, &IID_IDXGIDevice, (void **)&unk);
4857 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4858 IUnknown_Release(unk);
4860 handle1 = NULL;
4861 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4862 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4863 ok(handle != handle1, "Unexpected handle.\n");
4865 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4866 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4868 /* Already closed. */
4869 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4870 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4872 handle = NULL;
4873 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4874 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4876 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4877 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4879 hr = IMFDXGIDeviceManager_TestDevice(manager, handle1);
4880 ok(hr == E_HANDLE, "Unexpected hr %#x.\n", hr);
4882 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4883 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4884 ok(device == d3d11_dev2, "Unexpected device pointer.\n");
4885 ID3D11Device_Release(device);
4887 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4888 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4890 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4891 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4893 hr = IMFDXGIDeviceManager_UnlockDevice(manager, UlongToHandle(100), FALSE);
4894 ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr);
4896 /* Locked with one handle, unlock with another. */
4897 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4898 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4900 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4901 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4903 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4904 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4906 ID3D11Device_Release(device);
4908 /* Closing unlocks the device. */
4909 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4910 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4912 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4913 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4914 ID3D11Device_Release(device);
4916 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4917 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4919 /* Open two handles. */
4920 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle);
4921 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4923 hr = IMFDXGIDeviceManager_OpenDeviceHandle(manager, &handle1);
4924 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4926 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4927 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4928 ID3D11Device_Release(device);
4930 hr = IMFDXGIDeviceManager_LockDevice(manager, handle1, &IID_ID3D11Device, (void **)&device, FALSE);
4931 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4932 ID3D11Device_Release(device);
4934 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4935 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4937 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle, FALSE);
4938 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4940 param.manager = manager;
4941 param.handle = handle;
4942 param.lock = TRUE;
4943 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4944 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4945 GetExitCodeThread(thread, (DWORD *)&hr);
4946 ok(hr == MF_E_DXGI_VIDEO_DEVICE_LOCKED, "Unexpected hr %#x.\n", hr);
4947 CloseHandle(thread);
4949 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4950 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4952 hr = IMFDXGIDeviceManager_UnlockDevice(manager, handle1, FALSE);
4953 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
4955 /* Lock on main thread, unlock on another. */
4956 hr = IMFDXGIDeviceManager_LockDevice(manager, handle, &IID_ID3D11Device, (void **)&device, FALSE);
4957 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4958 ID3D11Device_Release(device);
4960 param.manager = manager;
4961 param.handle = handle;
4962 param.lock = FALSE;
4963 thread = CreateThread(NULL, 0, test_device_manager_thread, &param, 0, NULL);
4964 ok(!WaitForSingleObject(thread, 1000), "Wait for a test thread failed.\n");
4965 GetExitCodeThread(thread, (DWORD *)&hr);
4966 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4967 CloseHandle(thread);
4969 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle1);
4970 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4972 hr = IMFDXGIDeviceManager_CloseDeviceHandle(manager, handle);
4973 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
4975 IMFDXGIDeviceManager_Release(manager);
4976 EXPECT_REF(d3d11_dev2, 1);
4977 ID3D11Device_Release(d3d11_dev);
4978 ID3D11Device_Release(d3d11_dev2);
4979 IMFDXGIDeviceManager_Release(manager2);
4982 static void test_MFCreateTransformActivate(void)
4984 IMFActivate *activate;
4985 UINT32 count;
4986 HRESULT hr;
4988 if (!pMFCreateTransformActivate)
4990 win_skip("MFCreateTransformActivate() is not available.\n");
4991 return;
4994 hr = pMFCreateTransformActivate(&activate);
4995 ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr);
4997 hr = IMFActivate_GetCount(activate, &count);
4998 ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr);
4999 ok(!count, "Unexpected attribute count %u.\n", count);
5001 IMFActivate_Release(activate);
5004 static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj)
5006 if (IsEqualIID(riid, &IID_IClassFactory) ||
5007 IsEqualIID(riid, &IID_IUnknown))
5009 *obj = iface;
5010 IClassFactory_AddRef(iface);
5011 return S_OK;
5014 *obj = NULL;
5015 return E_NOINTERFACE;
5018 static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface)
5020 return 2;
5023 static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface)
5025 return 1;
5028 static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
5030 ok(0, "Unexpected call.\n");
5031 return E_NOTIMPL;
5034 static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock)
5036 return S_OK;
5039 static const IClassFactoryVtbl test_mft_factory_vtbl =
5041 test_mft_factory_QueryInterface,
5042 test_mft_factory_AddRef,
5043 test_mft_factory_Release,
5044 test_mft_factory_CreateInstance,
5045 test_mft_factory_LockServer,
5048 static void test_MFTRegisterLocal(void)
5050 IClassFactory test_factory = { &test_mft_factory_vtbl };
5051 MFT_REGISTER_TYPE_INFO input_types[1];
5052 IMFActivate **activate;
5053 UINT32 count, count2;
5054 HRESULT hr;
5056 if (!pMFTRegisterLocal)
5058 win_skip("MFTRegisterLocal() is not available.\n");
5059 return;
5062 input_types[0].guidMajorType = MFMediaType_Audio;
5063 input_types[0].guidSubtype = MFAudioFormat_PCM;
5064 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5065 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5067 hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL);
5068 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5070 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count);
5071 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5072 ok(count > 0, "Unexpected count %u.\n", count);
5073 CoTaskMemFree(activate);
5075 hr = pMFTUnregisterLocal(&test_factory);
5076 ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
5078 hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2);
5079 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5080 ok(count2 < count, "Unexpected count %u.\n", count2);
5081 CoTaskMemFree(activate);
5083 hr = pMFTUnregisterLocal(&test_factory);
5084 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5086 hr = pMFTUnregisterLocal(NULL);
5087 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5089 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5090 0, NULL);
5091 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5093 hr = pMFTUnregisterLocal(NULL);
5094 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5096 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5097 ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
5099 hr = pMFTRegisterLocalByCLSID(&MFT_CATEGORY_OTHER, &MFT_CATEGORY_OTHER, L"Local MFT name 2", 0, 1, input_types,
5100 0, NULL);
5101 ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
5103 hr = pMFTUnregisterLocalByCLSID(MFT_CATEGORY_OTHER);
5104 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5107 static void test_queue_com(void)
5109 static int system_queues[] =
5111 MFASYNC_CALLBACK_QUEUE_STANDARD,
5112 MFASYNC_CALLBACK_QUEUE_RT,
5113 MFASYNC_CALLBACK_QUEUE_IO,
5114 MFASYNC_CALLBACK_QUEUE_TIMER,
5115 MFASYNC_CALLBACK_QUEUE_MULTITHREADED,
5116 MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION,
5119 static int user_queues[] =
5121 MF_STANDARD_WORKQUEUE,
5122 MF_WINDOW_WORKQUEUE,
5123 MF_MULTITHREADED_WORKQUEUE,
5126 char path_name[MAX_PATH];
5127 PROCESS_INFORMATION info;
5128 STARTUPINFOA startup;
5129 char **argv;
5130 int i;
5132 if (!pCoGetApartmentType)
5134 win_skip("CoGetApartmentType() is not available.\n");
5135 return;
5138 winetest_get_mainargs(&argv);
5140 for (i = 0; i < ARRAY_SIZE(system_queues); ++i)
5142 memset(&startup, 0, sizeof(startup));
5143 startup.cb = sizeof(startup);
5144 sprintf(path_name, "%s mfplat s%d", argv[0], system_queues[i]);
5145 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5146 "CreateProcess failed.\n" );
5147 wait_child_process(info.hProcess);
5148 CloseHandle(info.hProcess);
5149 CloseHandle(info.hThread);
5152 for (i = 0; i < ARRAY_SIZE(user_queues); ++i)
5154 memset(&startup, 0, sizeof(startup));
5155 startup.cb = sizeof(startup);
5156 sprintf(path_name, "%s mfplat u%d", argv[0], user_queues[i]);
5157 ok(CreateProcessA( NULL, path_name, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info),
5158 "CreateProcess failed.\n" );
5159 wait_child_process(info.hProcess);
5160 CloseHandle(info.hProcess);
5161 CloseHandle(info.hThread);
5165 static HRESULT WINAPI test_queue_com_state_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
5167 struct test_callback *callback = impl_from_IMFAsyncCallback(iface);
5168 APTTYPEQUALIFIER qualifier;
5169 APTTYPE com_type;
5170 HRESULT hr;
5172 hr = pCoGetApartmentType(&com_type, &qualifier);
5173 ok(SUCCEEDED(hr), "Failed to get apartment type, hr %#x.\n", hr);
5174 if (SUCCEEDED(hr))
5176 todo_wine {
5177 if (callback->param == MFASYNC_CALLBACK_QUEUE_LONG_FUNCTION)
5178 ok(com_type == APTTYPE_MAINSTA && qualifier == APTTYPEQUALIFIER_NONE,
5179 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5180 else
5181 ok(com_type == APTTYPE_MTA && qualifier == APTTYPEQUALIFIER_NONE,
5182 "%#x: unexpected type %u, qualifier %u.\n", callback->param, com_type, qualifier);
5186 SetEvent(callback->event);
5187 return S_OK;
5190 static const IMFAsyncCallbackVtbl test_queue_com_state_callback_vtbl =
5192 testcallback_QueryInterface,
5193 testcallback_AddRef,
5194 testcallback_Release,
5195 testcallback_GetParameters,
5196 test_queue_com_state_callback_Invoke,
5199 static void test_queue_com_state(const char *name)
5201 struct test_callback callback = { { &test_queue_com_state_callback_vtbl } };
5202 DWORD queue, queue_type;
5203 HRESULT hr;
5205 callback.event = CreateEventA(NULL, FALSE, FALSE, NULL);
5207 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
5208 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
5210 if (name[0] == 's')
5212 callback.param = name[1] - '0';
5213 hr = MFPutWorkItem(callback.param, &callback.IMFAsyncCallback_iface, NULL);
5214 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5215 WaitForSingleObject(callback.event, INFINITE);
5217 else if (name[0] == 'u')
5219 queue_type = name[1] - '0';
5221 hr = pMFAllocateWorkQueueEx(queue_type, &queue);
5222 ok(hr == S_OK || broken(queue_type == MF_MULTITHREADED_WORKQUEUE && hr == E_INVALIDARG) /* Win7 */,
5223 "Failed to allocate a queue of type %u, hr %#x.\n", queue_type, hr);
5225 if (SUCCEEDED(hr))
5227 callback.param = queue;
5228 hr = MFPutWorkItem(queue, &callback.IMFAsyncCallback_iface, NULL);
5229 ok(SUCCEEDED(hr), "Failed to queue work item, hr %#x.\n", hr);
5230 WaitForSingleObject(callback.event, INFINITE);
5232 hr = MFUnlockWorkQueue(queue);
5233 ok(hr == S_OK, "Failed to unlock the queue, hr %#x.\n", hr);
5237 CloseHandle(callback.event);
5239 hr = MFShutdown();
5240 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
5243 static void test_MFGetStrideForBitmapInfoHeader(void)
5245 static const struct stride_test
5247 const GUID *subtype;
5248 unsigned int width;
5249 LONG stride;
5251 stride_tests[] =
5253 { &MFVideoFormat_RGB8, 3, -4 },
5254 { &MFVideoFormat_RGB8, 1, -4 },
5255 { &MFVideoFormat_RGB555, 3, -8 },
5256 { &MFVideoFormat_RGB555, 1, -4 },
5257 { &MFVideoFormat_RGB565, 3, -8 },
5258 { &MFVideoFormat_RGB565, 1, -4 },
5259 { &MFVideoFormat_RGB24, 3, -12 },
5260 { &MFVideoFormat_RGB24, 1, -4 },
5261 { &MFVideoFormat_RGB32, 3, -12 },
5262 { &MFVideoFormat_RGB32, 1, -4 },
5263 { &MFVideoFormat_ARGB32, 3, -12 },
5264 { &MFVideoFormat_ARGB32, 1, -4 },
5265 { &MFVideoFormat_A2R10G10B10, 3, -12 },
5266 { &MFVideoFormat_A2R10G10B10, 1, -4 },
5267 { &MFVideoFormat_A16B16G16R16F, 3, -24 },
5268 { &MFVideoFormat_A16B16G16R16F, 1, -8 },
5270 /* YUV */
5271 { &MFVideoFormat_NV12, 1, 1 },
5272 { &MFVideoFormat_NV12, 2, 2 },
5273 { &MFVideoFormat_NV12, 3, 3 },
5274 { &MFVideoFormat_AYUV, 1, 4 },
5275 { &MFVideoFormat_AYUV, 4, 16 },
5276 { &MFVideoFormat_AYUV, 5, 20 },
5277 { &MFVideoFormat_IMC1, 1, 4 },
5278 { &MFVideoFormat_IMC1, 2, 4 },
5279 { &MFVideoFormat_IMC1, 3, 8 },
5280 { &MFVideoFormat_IMC3, 1, 4 },
5281 { &MFVideoFormat_IMC3, 2, 4 },
5282 { &MFVideoFormat_IMC3, 3, 8 },
5283 { &MFVideoFormat_IMC2, 1, 1 },
5284 { &MFVideoFormat_IMC2, 2, 2 },
5285 { &MFVideoFormat_IMC2, 3, 3 },
5286 { &MFVideoFormat_IMC4, 1, 1 },
5287 { &MFVideoFormat_IMC4, 2, 2 },
5288 { &MFVideoFormat_IMC4, 3, 3 },
5289 { &MFVideoFormat_YV12, 1, 1 },
5290 { &MFVideoFormat_YV12, 2, 2 },
5291 { &MFVideoFormat_YV12, 3, 3 },
5292 { &MFVideoFormat_YV12, 320, 320 },
5293 { &MFVideoFormat_I420, 1, 1 },
5294 { &MFVideoFormat_I420, 2, 2 },
5295 { &MFVideoFormat_I420, 3, 3 },
5296 { &MFVideoFormat_I420, 320, 320 },
5298 unsigned int i;
5299 LONG stride;
5300 HRESULT hr;
5302 if (!pMFGetStrideForBitmapInfoHeader)
5304 win_skip("MFGetStrideForBitmapInfoHeader() is not available.\n");
5305 return;
5308 hr = pMFGetStrideForBitmapInfoHeader(MAKEFOURCC('H','2','6','4'), 1, &stride);
5309 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5311 for (i = 0; i < ARRAY_SIZE(stride_tests); ++i)
5313 hr = pMFGetStrideForBitmapInfoHeader(stride_tests[i].subtype->Data1, stride_tests[i].width, &stride);
5314 ok(hr == S_OK, "%u: failed to get stride, hr %#x.\n", i, hr);
5315 ok(stride == stride_tests[i].stride, "%u: format %s, unexpected stride %d, expected %d.\n", i,
5316 wine_dbgstr_an((char *)&stride_tests[i].subtype->Data1, 4), stride, stride_tests[i].stride);
5320 static void test_MFCreate2DMediaBuffer(void)
5322 static const struct _2d_buffer_test
5324 unsigned int width;
5325 unsigned int height;
5326 unsigned int fourcc;
5327 unsigned int contiguous_length;
5328 int pitch;
5329 unsigned int plane_multiplier;
5330 } _2d_buffer_tests[] =
5332 { 2, 2, MAKEFOURCC('N','V','1','2'), 6, 64 },
5333 { 4, 2, MAKEFOURCC('N','V','1','2'), 12, 64 },
5334 { 2, 4, MAKEFOURCC('N','V','1','2'), 12, 64 },
5335 { 1, 3, MAKEFOURCC('N','V','1','2'), 4, 64 },
5337 { 2, 2, MAKEFOURCC('I','M','C','2'), 6, 128 },
5338 { 4, 2, MAKEFOURCC('I','M','C','2'), 12, 128 },
5339 { 2, 4, MAKEFOURCC('I','M','C','2'), 12, 128 },
5340 { 2, 2, MAKEFOURCC('I','M','C','4'), 6, 128 },
5341 { 4, 2, MAKEFOURCC('I','M','C','4'), 12, 128 },
5342 { 2, 4, MAKEFOURCC('I','M','C','4'), 12, 128 },
5344 { 4, 2, MAKEFOURCC('I','M','C','1'), 32, 128, 2 },
5345 { 4, 4, MAKEFOURCC('I','M','C','1'), 64, 128, 2 },
5346 { 4, 16, MAKEFOURCC('I','M','C','1'), 256, 128, 2 },
5347 { 4, 20, MAKEFOURCC('I','M','C','1'), 320, 128, 2 },
5349 { 4, 2, MAKEFOURCC('I','M','C','3'), 32, 128, 2 },
5350 { 4, 4, MAKEFOURCC('I','M','C','3'), 64, 128, 2 },
5351 { 4, 16, MAKEFOURCC('I','M','C','3'), 256, 128, 2 },
5352 { 4, 20, MAKEFOURCC('I','M','C','3'), 320, 128, 2 },
5354 { 4, 2, MAKEFOURCC('Y','V','1','2'), 12, 128 },
5355 { 4, 4, MAKEFOURCC('Y','V','1','2'), 24, 128 },
5356 { 4, 16, MAKEFOURCC('Y','V','1','2'), 96, 128 },
5358 { 4, 2, MAKEFOURCC('A','Y','U','V'), 32, 64 },
5359 { 4, 4, MAKEFOURCC('A','Y','U','V'), 64, 64 },
5360 { 4, 16, MAKEFOURCC('A','Y','U','V'), 256, 64 },
5362 { 4, 2, MAKEFOURCC('Y','U','Y','2'), 16, 64 },
5363 { 4, 4, MAKEFOURCC('Y','U','Y','2'), 32, 64 },
5364 { 4, 16, MAKEFOURCC('Y','U','Y','2'), 128, 64 },
5366 { 4, 2, MAKEFOURCC('U','Y','V','Y'), 16, 64 },
5367 { 4, 4, MAKEFOURCC('U','Y','V','Y'), 32, 64 },
5368 { 4, 16, MAKEFOURCC('U','Y','V','Y'), 128, 64 },
5370 { 2, 4, D3DFMT_A8R8G8B8, 32, 64 },
5371 { 1, 4, D3DFMT_A8R8G8B8, 16, 64 },
5372 { 4, 1, D3DFMT_A8R8G8B8, 16, 64 },
5374 unsigned int max_length, length, length2;
5375 BYTE *buffer_start, *data, *data2;
5376 IMF2DBuffer2 *_2dbuffer2;
5377 IMF2DBuffer *_2dbuffer;
5378 IMFMediaBuffer *buffer;
5379 int i, pitch, pitch2;
5380 HRESULT hr;
5381 BOOL ret;
5383 if (!pMFCreate2DMediaBuffer)
5385 win_skip("MFCreate2DMediaBuffer() is not available.\n");
5386 return;
5389 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('H','2','6','4'), FALSE, &buffer);
5390 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5392 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, NULL);
5393 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5395 /* YUV formats can't be bottom-up. */
5396 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), TRUE, &buffer);
5397 ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
5399 hr = pMFCreate2DMediaBuffer(2, 3, MAKEFOURCC('N','V','1','2'), FALSE, &buffer);
5400 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5402 check_interface(buffer, &IID_IMFGetService, TRUE);
5403 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5405 /* Full backing buffer size, with 64 bytes per row alignment. */
5406 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5407 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5408 ok(max_length > 0, "Unexpected length %u.\n", max_length);
5410 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5411 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5412 ok(!length, "Unexpected length.\n");
5414 hr = IMFMediaBuffer_SetCurrentLength(buffer, 10);
5415 ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr);
5417 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5418 ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr);
5419 ok(length == 10, "Unexpected length.\n");
5421 /* Linear lock/unlock. */
5423 hr = IMFMediaBuffer_Lock(buffer, NULL, &max_length, &length);
5424 ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
5426 /* Linear locking call returns plane size.*/
5427 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &length);
5428 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5429 ok(max_length == length, "Unexpected length.\n");
5431 length = 0;
5432 pMFGetPlaneSize(MAKEFOURCC('N','V','1','2'), 2, 3, &length);
5433 ok(max_length == length && length == 9, "Unexpected length %u.\n", length);
5435 /* Already locked */
5436 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5437 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5438 ok(data2 == data, "Unexpected pointer.\n");
5440 hr = IMFMediaBuffer_Unlock(buffer);
5441 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5443 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5444 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5446 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
5447 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5449 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5450 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5451 ok(length == 9, "Unexpected length %u.\n", length);
5453 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, NULL);
5454 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5456 /* 2D lock. */
5457 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5458 ok(hr == MF_E_UNEXPECTED, "Unexpected hr %#x.\n", hr);
5460 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5461 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5463 hr = IMFMediaBuffer_Unlock(buffer);
5464 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5466 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5467 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5469 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, NULL);
5470 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5472 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, NULL);
5473 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5475 hr = IMF2DBuffer_Lock2D(_2dbuffer, NULL, &pitch);
5476 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5478 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5479 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5480 ok(!!data, "Expected data pointer.\n");
5481 ok(pitch == 64, "Unexpected pitch %d.\n", pitch);
5483 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data2, &pitch);
5484 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5485 ok(data == data2, "Expected data pointer.\n");
5487 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, NULL, &pitch);
5488 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5490 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, NULL);
5491 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5493 /* Active 2D lock */
5494 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5495 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5497 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5498 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5500 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5501 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5503 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5504 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5506 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5507 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5509 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
5510 ok(hr == S_OK || broken(hr == E_NOINTERFACE), "Failed to get interface, hr %#x.\n", hr);
5512 if (SUCCEEDED(hr))
5514 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5515 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5517 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5518 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5520 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5521 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5523 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5524 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5526 /* Flags are ignored. */
5527 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data2, &pitch, &buffer_start, &length);
5528 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5530 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &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 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, NULL, &length);
5540 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5542 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data2, &pitch, &buffer_start, NULL);
5543 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
5545 IMF2DBuffer2_Release(_2dbuffer2);
5547 else
5548 win_skip("IMF2DBuffer2 is not supported.\n");
5550 IMF2DBuffer_Release(_2dbuffer);
5552 IMFMediaBuffer_Release(buffer);
5554 for (i = 0; i < ARRAY_SIZE(_2d_buffer_tests); ++i)
5556 const struct _2d_buffer_test *ptr = &_2d_buffer_tests[i];
5558 hr = pMFCreate2DMediaBuffer(ptr->width, ptr->height, ptr->fourcc, FALSE, &buffer);
5559 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5561 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5562 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
5564 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
5565 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5566 ok(length == ptr->contiguous_length, "%d: unexpected contiguous length %u for %u x %u, format %s.\n",
5567 i, length, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5569 hr = IMFMediaBuffer_Lock(buffer, &data, &length2, NULL);
5570 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5571 ok(length == ptr->contiguous_length, "%d: unexpected linear buffer length %u for %u x %u, format %s.\n",
5572 i, length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5574 hr = IMFMediaBuffer_Unlock(buffer);
5575 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5577 hr = pMFGetPlaneSize(ptr->fourcc, ptr->width, ptr->height, &length2);
5578 ok(hr == S_OK, "Failed to get plane size, hr %#x.\n", hr);
5579 if (ptr->plane_multiplier)
5580 length2 *= ptr->plane_multiplier;
5581 ok(length2 == length, "%d: contiguous length %u does not match plane size %u, %u x %u, format %s.\n", i, length,
5582 length2, ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5584 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5585 ok(hr == S_OK, "Failed to lock buffer, hr %#x.\n", hr);
5587 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data2, &pitch2);
5588 ok(hr == S_OK, "Failed to get scanline, hr %#x.\n", hr);
5589 ok(data2 == data, "Unexpected data pointer.\n");
5590 ok(pitch == pitch2, "Unexpected pitch.\n");
5592 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5593 ok(hr == S_OK, "Failed to unlock buffer, hr %#x.\n", hr);
5595 ok(pitch == ptr->pitch, "%d: unexpected pitch %d, expected %d, %u x %u, format %s.\n", i, pitch, ptr->pitch,
5596 ptr->width, ptr->height, wine_dbgstr_an((char *)&ptr->fourcc, 4));
5598 ret = TRUE;
5599 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &ret);
5600 ok(hr == S_OK, "Failed to get format flag, hr %#x.\n", hr);
5601 ok(!ret, "%d: unexpected format flag %d.\n", i, ret);
5603 IMF2DBuffer_Release(_2dbuffer);
5605 IMFMediaBuffer_Release(buffer);
5609 static void test_MFCreateMediaBufferFromMediaType(void)
5611 static struct audio_buffer_test
5613 unsigned int duration;
5614 unsigned int min_length;
5615 unsigned int min_alignment;
5616 unsigned int block_alignment;
5617 unsigned int bytes_per_second;
5618 unsigned int buffer_length;
5619 } audio_tests[] =
5621 { 0, 0, 0, 4, 0, 20 },
5622 { 0, 16, 0, 4, 0, 20 },
5623 { 0, 0, 32, 4, 0, 36 },
5624 { 0, 64, 32, 4, 0, 64 },
5625 { 1, 0, 0, 4, 16, 36 },
5626 { 2, 0, 0, 4, 16, 52 },
5628 IMFMediaBuffer *buffer;
5629 UINT32 length;
5630 HRESULT hr;
5631 IMFMediaType *media_type;
5632 unsigned int i;
5634 if (!pMFCreateMediaBufferFromMediaType)
5636 win_skip("MFCreateMediaBufferFromMediaType() is not available.\n");
5637 return;
5640 hr = pMFCreateMediaBufferFromMediaType(NULL, 0, 0, 0, &buffer);
5641 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5643 hr = MFCreateMediaType(&media_type);
5644 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5646 hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
5647 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5649 for (i = 0; i < ARRAY_SIZE(audio_tests); ++i)
5651 const struct audio_buffer_test *ptr = &audio_tests[i];
5653 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, ptr->block_alignment);
5654 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5656 hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, ptr->bytes_per_second);
5657 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
5659 hr = pMFCreateMediaBufferFromMediaType(media_type, ptr->duration * 10000000, ptr->min_length,
5660 ptr->min_alignment, &buffer);
5661 ok(hr == S_OK || broken(FAILED(hr)) /* Win8 */, "Unexpected hr %#x.\n", hr);
5662 if (FAILED(hr))
5663 break;
5665 check_interface(buffer, &IID_IMFGetService, FALSE);
5667 hr = IMFMediaBuffer_GetMaxLength(buffer, &length);
5668 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5669 ok(ptr->buffer_length == length, "%d: unexpected buffer length %u, expected %u.\n", i, length, ptr->buffer_length);
5671 IMFMediaBuffer_Release(buffer);
5674 IMFMediaType_Release(media_type);
5677 static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *format)
5679 GUID guid, subtype;
5680 UINT32 value;
5681 HRESULT hr;
5683 hr = IMFMediaType_GetMajorType(mediatype, &guid);
5684 ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr);
5685 ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type %s.\n", wine_dbgstr_guid(&guid));
5687 hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid);
5688 ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr);
5690 if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
5692 const WAVEFORMATEXTENSIBLE *fex = (const WAVEFORMATEXTENSIBLE *)format;
5693 ok(IsEqualGUID(&guid, &fex->SubFormat), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5695 if (fex->dwChannelMask)
5697 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value);
5698 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5699 ok(value == fex->dwChannelMask, "Unexpected CHANNEL_MASK %#x.\n", value);
5702 if (format->wBitsPerSample && fex->Samples.wValidBitsPerSample)
5704 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value);
5705 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5706 ok(value == fex->Samples.wValidBitsPerSample, "Unexpected VALID_BITS_PER_SAMPLE %#x.\n", value);
5709 else
5711 memcpy(&subtype, &MFAudioFormat_Base, sizeof(subtype));
5712 subtype.Data1 = format->wFormatTag;
5713 ok(IsEqualGUID(&guid, &subtype), "Unexpected subtype %s.\n", wine_dbgstr_guid(&guid));
5715 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, &value);
5716 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5717 ok(value, "Unexpected value.\n");
5720 if (format->nChannels)
5722 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value);
5723 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5724 ok(value == format->nChannels, "Unexpected NUM_CHANNELS %u.\n", value);
5727 if (format->nSamplesPerSec)
5729 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value);
5730 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5731 ok(value == format->nSamplesPerSec, "Unexpected SAMPLES_PER_SECOND %u.\n", value);
5734 if (format->nAvgBytesPerSec)
5736 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value);
5737 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5738 ok(value == format->nAvgBytesPerSec, "Unexpected AVG_BYTES_PER_SECOND %u.\n", value);
5741 if (format->nBlockAlign)
5743 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value);
5744 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5745 ok(value == format->nBlockAlign, "Unexpected BLOCK_ALIGNMENT %u.\n", value);
5748 if (format->wBitsPerSample)
5750 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value);
5751 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5752 ok(value == format->wBitsPerSample, "Unexpected BITS_PER_SAMPLE %u.\n", value);
5755 /* Only set for uncompressed formats. */
5756 hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
5757 if (IsEqualGUID(&guid, &MFAudioFormat_Float) ||
5758 IsEqualGUID(&guid, &MFAudioFormat_PCM))
5760 ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
5761 ok(value, "Unexpected ALL_SAMPLES_INDEPENDENT value.\n");
5763 else
5764 ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n");
5767 static void test_MFInitMediaTypeFromWaveFormatEx(void)
5769 static const WAVEFORMATEX waveformatex_tests[] =
5771 { WAVE_FORMAT_PCM, 2, 44100, 0, 2, 8 },
5772 { WAVE_FORMAT_PCM, 2, 44100, 1, 2, 8 },
5773 { WAVE_FORMAT_PCM, 0, 44100, 0, 0, 0 },
5774 { WAVE_FORMAT_PCM, 0, 0, 0, 0, 0 },
5775 { WAVE_FORMAT_IEEE_FLOAT, 2, 44100, 1, 2, 8 },
5776 { 1234, 0, 0, 0, 0, 0 },
5777 { WAVE_FORMAT_ALAW },
5778 { WAVE_FORMAT_CREATIVE_ADPCM },
5779 { WAVE_FORMAT_MPEGLAYER3 },
5780 { WAVE_FORMAT_MPEG_ADTS_AAC },
5781 { WAVE_FORMAT_ALAC },
5782 { WAVE_FORMAT_AMR_NB },
5783 { WAVE_FORMAT_AMR_WB },
5784 { WAVE_FORMAT_AMR_WP },
5785 { WAVE_FORMAT_DOLBY_AC3_SPDIF },
5786 { WAVE_FORMAT_DRM },
5787 { WAVE_FORMAT_DTS },
5788 { WAVE_FORMAT_FLAC },
5789 { WAVE_FORMAT_MPEG },
5790 { WAVE_FORMAT_WMAVOICE9 },
5791 { WAVE_FORMAT_OPUS },
5792 { WAVE_FORMAT_WMAUDIO2 },
5793 { WAVE_FORMAT_WMAUDIO3 },
5794 { WAVE_FORMAT_WMAUDIO_LOSSLESS },
5795 { WAVE_FORMAT_WMASPDIF },
5798 UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES];
5799 WAVEFORMATEXTENSIBLE waveformatext;
5800 MPEGLAYER3WAVEFORMAT mp3format;
5801 IMFMediaType *mediatype;
5802 unsigned int i, size;
5803 HRESULT hr;
5805 hr = MFCreateMediaType(&mediatype);
5806 ok(hr == S_OK, "Failed to create mediatype, hr %#x.\n", hr);
5808 for (i = 0; i < ARRAY_SIZE(waveformatex_tests); ++i)
5810 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatex_tests[i], sizeof(waveformatex_tests[i]));
5811 ok(hr == S_OK, "%d: format %#x, failed to initialize media type, hr %#x.\n", i, waveformatex_tests[i].wFormatTag, hr);
5813 validate_media_type(mediatype, &waveformatex_tests[i]);
5815 waveformatext.Format = waveformatex_tests[i];
5816 waveformatext.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
5817 waveformatext.Format.cbSize = sizeof(waveformatext) - sizeof(waveformatext.Format);
5818 waveformatext.Samples.wSamplesPerBlock = 123;
5819 waveformatext.dwChannelMask = 0x8;
5820 memcpy(&waveformatext.SubFormat, &MFAudioFormat_Base, sizeof(waveformatext.SubFormat));
5821 waveformatext.SubFormat.Data1 = waveformatex_tests[i].wFormatTag;
5823 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, &waveformatext.Format, sizeof(waveformatext));
5824 ok(hr == S_OK, "Failed to initialize media type, hr %#x.\n", hr);
5826 hr = IMFMediaType_GetItem(mediatype, &MF_MT_USER_DATA, NULL);
5827 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
5829 validate_media_type(mediatype, &waveformatext.Format);
5832 /* MPEGLAYER3WAVEFORMAT */
5833 mp3format.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
5834 mp3format.wfx.nChannels = 2;
5835 mp3format.wfx.nSamplesPerSec = 44100;
5836 mp3format.wfx.nAvgBytesPerSec = 16000;
5837 mp3format.wfx.nBlockAlign = 1;
5838 mp3format.wfx.wBitsPerSample = 0;
5839 mp3format.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
5840 mp3format.wID = MPEGLAYER3_ID_MPEG;
5841 mp3format.fdwFlags = 0;
5842 mp3format.nBlockSize = 417;
5843 mp3format.nFramesPerBlock = 0;
5844 mp3format.nCodecDelay = 0;
5846 hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&mp3format, sizeof(mp3format));
5847 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5849 validate_media_type(mediatype, &mp3format.wfx);
5850 hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
5851 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5852 ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size);
5853 ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
5855 IMFMediaType_Release(mediatype);
5858 static void test_MFCreateMFVideoFormatFromMFMediaType(void)
5860 MFVIDEOFORMAT *video_format;
5861 IMFMediaType *media_type;
5862 UINT32 size;
5863 HRESULT hr;
5865 hr = MFCreateMediaType(&media_type);
5866 ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
5868 hr = MFCreateMFVideoFormatFromMFMediaType(media_type, &video_format, &size);
5869 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5870 ok(!!video_format, "Unexpected format.\n");
5871 ok(video_format->dwSize == size && size == sizeof(*video_format), "Unexpected size %u.\n", size);
5872 CoTaskMemFree(video_format);
5874 IMFMediaType_Release(media_type);
5877 static void test_MFCreateDXSurfaceBuffer(void)
5879 IDirect3DSurface9 *backbuffer = NULL, *surface;
5880 IDirect3DSwapChain9 *swapchain;
5881 DWORD length, max_length;
5882 IDirect3DDevice9 *device;
5883 IMF2DBuffer2 *_2dbuffer2;
5884 IMFMediaBuffer *buffer;
5885 IMF2DBuffer *_2dbuffer;
5886 BYTE *data, *data2;
5887 IMFGetService *gs;
5888 IDirect3D9 *d3d;
5889 HWND window;
5890 HRESULT hr;
5891 LONG pitch;
5892 BOOL value;
5894 if (!pMFCreateDXSurfaceBuffer)
5896 win_skip("MFCreateDXSurfaceBuffer is not available.\n");
5897 return;
5900 window = create_window();
5901 d3d = Direct3DCreate9(D3D_SDK_VERSION);
5902 ok(!!d3d, "Failed to create a D3D object.\n");
5903 if (!(device = create_device(d3d, window)))
5905 skip("Failed to create a D3D device, skipping tests.\n");
5906 goto done;
5909 hr = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain);
5910 ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr);
5912 hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
5913 ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr);
5914 ok(backbuffer != NULL, "The back buffer is NULL\n");
5916 IDirect3DSwapChain9_Release(swapchain);
5918 hr = pMFCreateDXSurfaceBuffer(&IID_IUnknown, (IUnknown *)backbuffer, FALSE, &buffer);
5919 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
5921 hr = pMFCreateDXSurfaceBuffer(&IID_IDirect3DSurface9, (IUnknown *)backbuffer, FALSE, &buffer);
5922 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
5924 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
5925 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
5926 check_interface(buffer, &IID_IMFGetService, TRUE);
5928 /* Surface is accessible. */
5929 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFGetService, (void **)&gs);
5930 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5931 hr = IMFGetService_GetService(gs, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&surface);
5932 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5933 ok(surface == backbuffer, "Unexpected surface pointer.\n");
5934 IDirect3DSurface9_Release(surface);
5935 IMFGetService_Release(gs);
5937 max_length = 0;
5938 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
5939 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5940 ok(!!max_length, "Unexpected length %u.\n", max_length);
5942 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5943 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5944 ok(!length, "Unexpected length %u.\n", length);
5946 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
5947 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5949 hr = IMFMediaBuffer_GetCurrentLength(buffer, &length);
5950 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
5951 ok(length == 2 * max_length, "Unexpected length %u.\n", length);
5953 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length);
5954 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5955 ok(length == max_length, "Unexpected length.\n");
5957 /* Unlock twice. */
5958 hr = IMFMediaBuffer_Unlock(buffer);
5959 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5961 hr = IMFMediaBuffer_Unlock(buffer);
5962 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5964 /* Lock twice. */
5965 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
5966 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5968 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5969 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5970 ok(data == data2, "Unexpected pointer.\n");
5972 hr = IMFMediaBuffer_Unlock(buffer);
5973 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5975 hr = IMFMediaBuffer_Unlock(buffer);
5976 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5978 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2dbuffer);
5979 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5981 /* Unlocked. */
5982 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5983 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
5985 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5986 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5988 hr = IMF2DBuffer_GetScanline0AndPitch(_2dbuffer, &data, &pitch);
5989 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5991 hr = IMFMediaBuffer_Lock(buffer, &data2, NULL, NULL);
5992 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
5994 hr = IMF2DBuffer_Lock2D(_2dbuffer, &data, &pitch);
5995 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
5997 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
5998 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6000 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6001 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6003 hr = IMF2DBuffer_Unlock2D(_2dbuffer);
6004 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6006 hr = IMF2DBuffer_IsContiguousFormat(_2dbuffer, &value);
6007 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6008 ok(!value, "Unexpected return value %d.\n", value);
6010 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, NULL);
6011 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6012 hr = IMF2DBuffer_GetContiguousLength(_2dbuffer, &length);
6013 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6014 ok(length == max_length, "Unexpected length %u.\n", length);
6016 IMF2DBuffer_Release(_2dbuffer);
6018 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer2, (void **)&_2dbuffer2);
6019 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6021 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Read, &data, &pitch, &data2, &length);
6022 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6023 ok(data == data2, "Unexpected scanline pointer.\n");
6024 memset(data, 0xab, 4);
6025 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6027 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_Write, &data, &pitch, &data2, &length);
6028 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6029 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6030 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6032 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6033 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6034 ok(data[0] == 0xab, "Unexpected leading byte.\n");
6035 hr = IMFMediaBuffer_Unlock(buffer);
6036 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6038 hr = IMF2DBuffer2_Lock2DSize(_2dbuffer2, MF2DBuffer_LockFlags_ReadWrite, &data, &pitch, &data2, &length);
6039 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6040 IMF2DBuffer2_Unlock2D(_2dbuffer2);
6042 IMF2DBuffer2_Release(_2dbuffer2);
6044 IMFMediaBuffer_Release(buffer);
6046 done:
6047 if (backbuffer)
6048 IDirect3DSurface9_Release(backbuffer);
6049 IDirect3D9_Release(d3d);
6050 DestroyWindow(window);
6053 static void test_MFCreateTrackedSample(void)
6055 IMFTrackedSample *tracked_sample;
6056 IMFSample *sample;
6057 IUnknown *unk;
6058 HRESULT hr;
6060 if (!pMFCreateTrackedSample)
6062 win_skip("MFCreateTrackedSample() is not available.\n");
6063 return;
6066 hr = pMFCreateTrackedSample(&tracked_sample);
6067 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6069 /* It's actually a sample. */
6070 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample);
6071 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6073 hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk);
6074 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6075 ok(unk == (IUnknown *)sample, "Unexpected pointer.\n");
6076 IUnknown_Release(unk);
6078 IMFSample_Release(sample);
6080 check_interface(tracked_sample, &IID_IMFDesiredSample, FALSE);
6082 IMFTrackedSample_Release(tracked_sample);
6085 static void test_MFFrameRateToAverageTimePerFrame(void)
6087 static const struct frame_rate_test
6089 unsigned int numerator;
6090 unsigned int denominator;
6091 UINT64 avgtime;
6092 } frame_rate_tests[] =
6094 { 60000, 1001, 166833 },
6095 { 30000, 1001, 333667 },
6096 { 24000, 1001, 417188 },
6097 { 60, 1, 166667 },
6098 { 30, 1, 333333 },
6099 { 50, 1, 200000 },
6100 { 25, 1, 400000 },
6101 { 24, 1, 416667 },
6103 { 39, 1, 256410 },
6104 { 120, 1, 83333 },
6106 unsigned int i;
6107 UINT64 avgtime;
6108 HRESULT hr;
6110 avgtime = 1;
6111 hr = MFFrameRateToAverageTimePerFrame(0, 0, &avgtime);
6112 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6113 ok(!avgtime, "Unexpected frame time.\n");
6115 avgtime = 1;
6116 hr = MFFrameRateToAverageTimePerFrame(0, 1001, &avgtime);
6117 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6118 ok(!avgtime, "Unexpected frame time.\n");
6120 for (i = 0; i < ARRAY_SIZE(frame_rate_tests); ++i)
6122 avgtime = 0;
6123 hr = MFFrameRateToAverageTimePerFrame(frame_rate_tests[i].numerator,
6124 frame_rate_tests[i].denominator, &avgtime);
6125 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6126 ok(avgtime == frame_rate_tests[i].avgtime, "%u: unexpected frame time %s, expected %s.\n",
6127 i, wine_dbgstr_longlong(avgtime), wine_dbgstr_longlong(frame_rate_tests[i].avgtime));
6131 static void test_MFMapDXGIFormatToDX9Format(void)
6133 static const struct format_pair
6135 DXGI_FORMAT dxgi_format;
6136 DWORD d3d9_format;
6138 formats_map[] =
6140 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6141 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6142 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6143 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6144 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6145 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6146 { DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6147 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6148 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6149 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6150 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6151 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6152 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6153 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6154 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6155 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6156 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6157 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6158 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6159 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6160 { DXGI_FORMAT_BC1_UNORM_SRGB, D3DFMT_DXT1 },
6161 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6162 { DXGI_FORMAT_BC2_UNORM_SRGB, D3DFMT_DXT2 },
6163 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6164 { DXGI_FORMAT_BC3_UNORM_SRGB, D3DFMT_DXT4 },
6165 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6166 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6167 { DXGI_FORMAT_B8G8R8A8_UNORM_SRGB, D3DFMT_A8R8G8B8 },
6168 { DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, D3DFMT_X8R8G8B8 },
6169 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6170 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6171 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6172 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6173 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6174 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6175 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6176 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6177 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6178 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6179 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6180 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6181 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6182 { DXGI_FORMAT_P8, D3DFMT_P8 },
6183 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6185 unsigned int i;
6186 DWORD format;
6188 if (!pMFMapDXGIFormatToDX9Format)
6190 win_skip("MFMapDXGIFormatToDX9Format is not available.\n");
6191 return;
6194 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6196 format = pMFMapDXGIFormatToDX9Format(formats_map[i].dxgi_format);
6197 ok(format == formats_map[i].d3d9_format, "Unexpected d3d9 format %#x, dxgi format %#x.\n", format, formats_map[i].dxgi_format);
6201 static void test_MFMapDX9FormatToDXGIFormat(void)
6203 static const struct format_pair
6205 DXGI_FORMAT dxgi_format;
6206 DWORD d3d9_format;
6208 formats_map[] =
6210 { DXGI_FORMAT_R32G32B32A32_FLOAT, D3DFMT_A32B32G32R32F },
6211 { DXGI_FORMAT_R16G16B16A16_FLOAT, D3DFMT_A16B16G16R16F },
6212 { DXGI_FORMAT_R16G16B16A16_UNORM, D3DFMT_A16B16G16R16 },
6213 { DXGI_FORMAT_R16G16B16A16_SNORM, D3DFMT_Q16W16V16U16 },
6214 { DXGI_FORMAT_R32G32_FLOAT, D3DFMT_G32R32F },
6215 { DXGI_FORMAT_R10G10B10A2_UNORM, D3DFMT_A2B10G10R10 },
6216 { DXGI_FORMAT_R8G8B8A8_SNORM, D3DFMT_Q8W8V8U8 },
6217 { DXGI_FORMAT_R16G16_FLOAT, D3DFMT_G16R16F },
6218 { DXGI_FORMAT_R16G16_UNORM, D3DFMT_G16R16 },
6219 { DXGI_FORMAT_R16G16_SNORM, D3DFMT_V16U16 },
6220 { DXGI_FORMAT_D32_FLOAT, D3DFMT_D32F_LOCKABLE },
6221 { DXGI_FORMAT_R32_FLOAT, D3DFMT_R32F },
6222 { DXGI_FORMAT_D24_UNORM_S8_UINT, D3DFMT_D24S8 },
6223 { DXGI_FORMAT_R8G8_SNORM, D3DFMT_V8U8 },
6224 { DXGI_FORMAT_R16_FLOAT, D3DFMT_R16F },
6225 { DXGI_FORMAT_R16_UNORM, D3DFMT_L16 },
6226 { DXGI_FORMAT_R8_UNORM, D3DFMT_L8 },
6227 { DXGI_FORMAT_A8_UNORM, D3DFMT_A8 },
6228 { DXGI_FORMAT_BC1_UNORM, D3DFMT_DXT1 },
6229 { DXGI_FORMAT_BC2_UNORM, D3DFMT_DXT2 },
6230 { DXGI_FORMAT_BC3_UNORM, D3DFMT_DXT4 },
6231 { DXGI_FORMAT_B8G8R8A8_UNORM, D3DFMT_A8R8G8B8 },
6232 { DXGI_FORMAT_B8G8R8X8_UNORM, D3DFMT_X8R8G8B8 },
6233 { DXGI_FORMAT_AYUV, MAKEFOURCC('A','Y','U','V') },
6234 { DXGI_FORMAT_Y410, MAKEFOURCC('Y','4','1','0') },
6235 { DXGI_FORMAT_Y416, MAKEFOURCC('Y','4','1','6') },
6236 { DXGI_FORMAT_NV12, MAKEFOURCC('N','V','1','2') },
6237 { DXGI_FORMAT_P010, MAKEFOURCC('P','0','1','0') },
6238 { DXGI_FORMAT_P016, MAKEFOURCC('P','0','1','6') },
6239 { DXGI_FORMAT_420_OPAQUE, MAKEFOURCC('4','2','0','O') },
6240 { DXGI_FORMAT_YUY2, D3DFMT_YUY2 },
6241 { DXGI_FORMAT_Y210, MAKEFOURCC('Y','2','1','0') },
6242 { DXGI_FORMAT_Y216, MAKEFOURCC('Y','2','1','6') },
6243 { DXGI_FORMAT_NV11, MAKEFOURCC('N','V','1','1') },
6244 { DXGI_FORMAT_AI44, MAKEFOURCC('A','I','4','4') },
6245 { DXGI_FORMAT_IA44, MAKEFOURCC('I','A','4','4') },
6246 { DXGI_FORMAT_P8, D3DFMT_P8 },
6247 { DXGI_FORMAT_A8P8, D3DFMT_A8P8 },
6249 DXGI_FORMAT format;
6250 unsigned int i;
6252 if (!pMFMapDX9FormatToDXGIFormat)
6254 win_skip("MFMapDX9FormatToDXGIFormat() is not available.\n");
6255 return;
6258 for (i = 0; i < ARRAY_SIZE(formats_map); ++i)
6260 format = pMFMapDX9FormatToDXGIFormat(formats_map[i].d3d9_format);
6261 ok(format == formats_map[i].dxgi_format, "Unexpected DXGI format %#x, d3d9 format %#x.\n",
6262 format, formats_map[i].d3d9_format);
6266 static HRESULT WINAPI test_notify_callback_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
6267 REFIID riid, void **obj)
6269 if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
6270 IsEqualIID(riid, &IID_IUnknown))
6272 *obj = iface;
6273 IMFVideoSampleAllocatorNotify_AddRef(iface);
6274 return S_OK;
6277 *obj = NULL;
6278 return E_NOINTERFACE;
6281 static ULONG WINAPI test_notify_callback_AddRef(IMFVideoSampleAllocatorNotify *iface)
6283 return 2;
6286 static ULONG WINAPI test_notify_callback_Release(IMFVideoSampleAllocatorNotify *iface)
6288 return 1;
6291 static HRESULT WINAPI test_notify_callback_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
6293 return E_NOTIMPL;
6296 static const IMFVideoSampleAllocatorNotifyVtbl test_notify_callback_vtbl =
6298 test_notify_callback_QueryInterface,
6299 test_notify_callback_AddRef,
6300 test_notify_callback_Release,
6301 test_notify_callback_NotifyRelease,
6304 static IMFMediaType * create_video_type(const GUID *subtype)
6306 IMFMediaType *video_type;
6307 HRESULT hr;
6309 hr = MFCreateMediaType(&video_type);
6310 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6312 hr = IMFMediaType_SetGUID(video_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
6313 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6315 hr = IMFMediaType_SetGUID(video_type, &MF_MT_SUBTYPE, subtype);
6316 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6318 return video_type;
6321 static ID3D11Device *create_d3d11_device(void)
6323 static const D3D_FEATURE_LEVEL default_feature_level[] =
6325 D3D_FEATURE_LEVEL_11_0,
6326 D3D_FEATURE_LEVEL_10_1,
6327 D3D_FEATURE_LEVEL_10_0,
6329 const D3D_FEATURE_LEVEL *feature_level;
6330 unsigned int feature_level_count;
6331 ID3D11Device *device;
6333 feature_level = default_feature_level;
6334 feature_level_count = ARRAY_SIZE(default_feature_level);
6336 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0,
6337 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6338 return device;
6339 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0,
6340 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6341 return device;
6342 if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0,
6343 feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL)))
6344 return device;
6346 return NULL;
6349 static void update_d3d11_texture(ID3D11Texture2D *texture, unsigned int sub_resource_idx,
6350 const BYTE *data, unsigned int src_pitch)
6352 ID3D11DeviceContext *immediate_context;
6353 ID3D11Device *device;
6355 ID3D11Texture2D_GetDevice(texture, &device);
6356 ID3D11Device_GetImmediateContext(device, &immediate_context);
6358 ID3D11DeviceContext_UpdateSubresource(immediate_context, (ID3D11Resource *)texture,
6359 sub_resource_idx, NULL, data, src_pitch, 0);
6361 ID3D11DeviceContext_Release(immediate_context);
6362 ID3D11Device_Release(device);
6365 static void test_dxgi_surface_buffer(void)
6367 DWORD max_length, cur_length, length, color;
6368 IMFDXGIBuffer *dxgi_buffer;
6369 D3D11_TEXTURE2D_DESC desc;
6370 ID3D11Texture2D *texture;
6371 IMF2DBuffer *_2d_buffer;
6372 IMFMediaBuffer *buffer;
6373 ID3D11Device *device;
6374 BYTE buff[64 * 64 * 4];
6375 BYTE *data, *data2;
6376 LONG pitch, pitch2;
6377 UINT index, size;
6378 IUnknown *obj;
6379 HRESULT hr;
6381 if (!pMFCreateDXGISurfaceBuffer)
6383 win_skip("MFCreateDXGISurfaceBuffer() is not available.\n");
6384 return;
6387 device = create_d3d11_device();
6389 memset(&desc, 0, sizeof(desc));
6390 desc.Width = 64;
6391 desc.Height = 64;
6392 desc.ArraySize = 1;
6393 desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
6394 desc.SampleDesc.Count = 1;
6395 desc.SampleDesc.Quality = 0;
6397 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6398 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6400 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, FALSE, &buffer);
6401 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6403 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6404 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6405 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6406 check_interface(buffer, &IID_IMFGetService, FALSE);
6408 max_length = 0;
6409 hr = IMFMediaBuffer_GetMaxLength(buffer, &max_length);
6410 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6411 ok(!!max_length, "Unexpected length %u.\n", max_length);
6413 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6414 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6415 ok(!cur_length, "Unexpected length %u.\n", cur_length);
6417 hr = IMFMediaBuffer_SetCurrentLength(buffer, 2 * max_length);
6418 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6420 hr = IMFMediaBuffer_GetCurrentLength(buffer, &cur_length);
6421 ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr);
6422 ok(cur_length == 2 * max_length, "Unexpected length %u.\n", cur_length);
6424 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6425 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6427 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, NULL);
6428 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6429 hr = IMF2DBuffer_GetContiguousLength(_2d_buffer, &length);
6430 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6431 ok(length == max_length, "Unexpected length %u.\n", length);
6432 IMF2DBuffer_Release(_2d_buffer);
6434 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6435 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6437 EXPECT_REF(texture, 2);
6438 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&obj);
6439 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6440 EXPECT_REF(texture, 3);
6441 ok(obj == (IUnknown *)texture, "Unexpected resource pointer.\n");
6442 IUnknown_Release(obj);
6444 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, NULL);
6445 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6447 hr = IMFDXGIBuffer_GetSubresourceIndex(dxgi_buffer, &index);
6448 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6449 ok(index == 0, "Unexpected subresource index.\n");
6451 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6452 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6454 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6455 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6457 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, (void *)device);
6458 ok(hr == HRESULT_FROM_WIN32(ERROR_OBJECT_ALREADY_EXISTS), "Unexpected hr %#x.\n", hr);
6460 hr = ID3D11Texture2D_GetPrivateData(texture, &IID_IMFDXGIBuffer, &size, &data);
6461 ok(hr == DXGI_ERROR_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6463 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_ID3D11Device, (void **)&obj);
6464 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6465 ok(obj == (IUnknown *)device, "Unexpected pointer.\n");
6466 IUnknown_Release(obj);
6468 hr = IMFDXGIBuffer_SetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, NULL);
6469 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6471 hr = IMFDXGIBuffer_GetUnknown(dxgi_buffer, &IID_IMFDXGIBuffer, &IID_IUnknown, (void **)&obj);
6472 ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#x.\n", hr);
6474 IMFDXGIBuffer_Release(dxgi_buffer);
6476 /* Texture updates. */
6477 color = get_d3d11_texture_color(texture, 0, 0);
6478 ok(!color, "Unexpected texture color %#x.\n", color);
6480 max_length = cur_length = 0;
6481 data = NULL;
6482 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6483 todo_wine {
6484 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6485 ok(max_length && max_length == cur_length, "Unexpected length %u.\n", max_length);
6487 if (data) *(DWORD *)data = ~0u;
6489 color = get_d3d11_texture_color(texture, 0, 0);
6490 ok(!color, "Unexpected texture color %#x.\n", color);
6492 hr = IMFMediaBuffer_Unlock(buffer);
6493 todo_wine
6494 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6496 color = get_d3d11_texture_color(texture, 0, 0);
6497 todo_wine
6498 ok(color == ~0u, "Unexpected texture color %#x.\n", color);
6500 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6501 todo_wine
6502 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6503 if (SUCCEEDED(hr))
6504 ok(*(DWORD *)data == ~0u, "Unexpected buffer %#x.\n", *(DWORD *)data);
6506 hr = IMFMediaBuffer_Unlock(buffer);
6507 todo_wine
6508 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6510 /* Lock2D()/Unlock2D() */
6511 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6512 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6514 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6515 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6517 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6518 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6519 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6521 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6522 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6523 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6525 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6526 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6527 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
6529 hr = IMFMediaBuffer_Lock(buffer, &data, &max_length, &cur_length);
6530 todo_wine
6531 ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr);
6533 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6534 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6536 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6537 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6539 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6540 ok(hr == HRESULT_FROM_WIN32(ERROR_WAS_UNLOCKED), "Unexpected hr %#x.\n", hr);
6542 IMF2DBuffer_Release(_2d_buffer);
6543 IMFMediaBuffer_Release(buffer);
6545 /* Bottom up. */
6546 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 0, TRUE, &buffer);
6547 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6549 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6550 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6552 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6553 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6554 ok(!!data && pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6556 hr = IMF2DBuffer_GetScanline0AndPitch(_2d_buffer, &data2, &pitch2);
6557 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6558 ok(data2 == data && pitch2 == pitch, "Unexpected data/pitch.\n");
6560 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6561 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6563 IMF2DBuffer_Release(_2d_buffer);
6564 IMFMediaBuffer_Release(buffer);
6566 ID3D11Texture2D_Release(texture);
6568 /* Subresource index 1. */
6569 hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture);
6570 ok(hr == S_OK, "Failed to create a texture, hr %#x.\n", hr);
6572 hr = pMFCreateDXGISurfaceBuffer(&IID_ID3D11Texture2D, (IUnknown *)texture, 1, FALSE, &buffer);
6573 ok(hr == S_OK, "Failed to create a buffer, hr %#x.\n", hr);
6575 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&_2d_buffer);
6576 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6578 /* Pitch reflects top level. */
6579 memset(buff, 0, sizeof(buff));
6580 *(DWORD *)buff = 0xff00ff00;
6581 update_d3d11_texture(texture, 1, buff, 64 * 4);
6583 hr = IMF2DBuffer_Lock2D(_2d_buffer, &data, &pitch);
6584 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6585 ok(pitch == desc.Width * 4, "Unexpected pitch %d.\n", pitch);
6586 ok(*(DWORD *)data == 0xff00ff00, "Unexpected color %#x.\n", *(DWORD *)data);
6588 hr = IMF2DBuffer_Unlock2D(_2d_buffer);
6589 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6591 IMF2DBuffer_Release(_2d_buffer);
6592 IMFMediaBuffer_Release(buffer);
6594 ID3D11Texture2D_Release(texture);
6596 ID3D11Device_Release(device);
6599 static void test_sample_allocator(void)
6601 IMFVideoSampleAllocatorNotify test_notify = { &test_notify_callback_vtbl };
6602 IMFMediaType *media_type, *video_type, *video_type2;
6603 IMFVideoSampleAllocatorCallback *allocator_cb;
6604 IMFVideoSampleAllocatorEx *allocatorex;
6605 IDirect3DDeviceManager9 *d3d9_manager;
6606 IMFVideoSampleAllocator *allocator;
6607 unsigned int i, buffer_count, token;
6608 IDirect3DDevice9 *d3d9_device;
6609 IMFDXGIDeviceManager *manager;
6610 IMFSample *sample, *sample2;
6611 IMFDXGIBuffer *dxgi_buffer;
6612 IMFAttributes *attributes;
6613 D3D11_TEXTURE2D_DESC desc;
6614 ID3D11Texture2D *texture;
6615 IMFMediaBuffer *buffer;
6616 ID3D11Device *device;
6617 LONG refcount, count;
6618 IDirect3D9 *d3d9;
6619 IUnknown *unk;
6620 HRESULT hr;
6621 BYTE *data;
6622 HWND window;
6623 static const unsigned int usage[] =
6625 D3D11_USAGE_DEFAULT,
6626 D3D11_USAGE_IMMUTABLE,
6627 D3D11_USAGE_DYNAMIC,
6628 D3D11_USAGE_STAGING,
6629 D3D11_USAGE_STAGING + 1,
6632 if (!pMFCreateVideoSampleAllocatorEx)
6634 win_skip("MFCreateVideoSampleAllocatorEx() is not available.\n");
6635 return;
6638 hr = pMFCreateVideoSampleAllocatorEx(&IID_IUnknown, (void **)&unk);
6639 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6641 check_interface(unk, &IID_IMFVideoSampleAllocator, TRUE);
6642 check_interface(unk, &IID_IMFVideoSampleAllocatorEx, TRUE);
6643 check_interface(unk, &IID_IMFVideoSampleAllocatorCallback, TRUE);
6645 IUnknown_Release(unk);
6647 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6648 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6650 hr = IMFVideoSampleAllocator_QueryInterface(allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6651 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6653 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6654 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6656 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, &test_notify);
6657 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6659 hr = IMFVideoSampleAllocatorCallback_SetCallback(allocator_cb, NULL);
6660 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6662 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, NULL);
6663 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
6665 count = 10;
6666 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6667 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6668 ok(!count, "Unexpected count %d.\n", count);
6670 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6671 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6673 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6674 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6676 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, NULL);
6677 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6679 hr = MFCreateMediaType(&media_type);
6680 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6682 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, media_type);
6683 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6685 video_type = create_video_type(&MFVideoFormat_RGB32);
6686 video_type2 = create_video_type(&MFVideoFormat_RGB32);
6688 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6689 ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr);
6691 /* Frame size is required. */
6692 hr = IMFMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6693 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6695 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 240);
6696 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6698 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6699 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6701 EXPECT_REF(video_type, 1);
6702 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6703 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6704 EXPECT_REF(video_type, 2);
6706 hr = IMFMediaType_SetUINT64(video_type2, &IID_IUnknown, (UINT64) 320 << 32 | 240);
6707 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6709 /* Setting identical type does not replace it. */
6710 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6711 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6712 EXPECT_REF(video_type, 2);
6713 EXPECT_REF(video_type2, 1);
6715 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 64 << 32 | 64);
6716 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6718 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type2);
6719 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6720 EXPECT_REF(video_type2, 2);
6721 EXPECT_REF(video_type, 1);
6723 /* Modify referenced type. */
6724 hr = IMFMediaType_SetUINT64(video_type2, &MF_MT_FRAME_SIZE, (UINT64) 320 << 32 | 64);
6725 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6727 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6728 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6729 EXPECT_REF(video_type, 2);
6730 EXPECT_REF(video_type2, 1);
6732 count = 0;
6733 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6734 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6735 ok(count == 1, "Unexpected count %d.\n", count);
6737 sample = NULL;
6738 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6739 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6740 refcount = get_refcount(sample);
6742 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6743 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6744 ok(!count, "Unexpected count %d.\n", count);
6746 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample2);
6747 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6749 /* Reinitialize with active sample. */
6750 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 2, video_type);
6751 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6752 ok(refcount == get_refcount(sample), "Unexpected refcount %u.\n", get_refcount(sample));
6753 EXPECT_REF(video_type, 2);
6755 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6756 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6757 todo_wine
6758 ok(!count, "Unexpected count %d.\n", count);
6760 check_interface(sample, &IID_IMFTrackedSample, TRUE);
6761 check_interface(sample, &IID_IMFDesiredSample, FALSE);
6763 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6764 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6766 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6767 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6768 check_interface(buffer, &IID_IMFGetService, TRUE);
6769 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
6771 IMFMediaBuffer_Release(buffer);
6773 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6774 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6775 ok(buffer_count == 1, "Unexpected buffer count %u.\n", buffer_count);
6777 IMFSample_Release(sample);
6779 hr = IMFVideoSampleAllocator_UninitializeSampleAllocator(allocator);
6780 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6781 todo_wine
6782 EXPECT_REF(video_type, 2);
6784 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6785 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6786 ok(!count, "Unexpected count %d.\n", count);
6788 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6789 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6791 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6792 IMFVideoSampleAllocator_Release(allocator);
6794 /* IMFVideoSampleAllocatorEx */
6795 hr = MFCreateAttributes(&attributes, 0);
6796 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6798 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6799 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6801 hr = IMFVideoSampleAllocatorEx_QueryInterface(allocatorex, &IID_IMFVideoSampleAllocatorCallback, (void **)&allocator_cb);
6802 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6804 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 1, 0, NULL, video_type);
6805 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6807 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_BUFFERS_PER_SAMPLE, 2);
6808 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6810 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6811 ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
6813 EXPECT_REF(attributes, 1);
6814 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6815 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6816 EXPECT_REF(attributes, 2);
6818 count = 0;
6819 hr = IMFVideoSampleAllocatorCallback_GetFreeSampleCount(allocator_cb, &count);
6820 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6821 ok(count == 1, "Unexpected count %d.\n", count);
6823 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6824 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6826 hr = IMFSample_GetBufferCount(sample, &buffer_count);
6827 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6828 ok(buffer_count == 2, "Unexpected buffer count %u.\n", buffer_count);
6830 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6831 ok(hr == MF_E_SAMPLEALLOCATOR_EMPTY, "Unexpected hr %#x.\n", hr);
6833 /* Reinitialize with already allocated samples. */
6834 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, NULL, video_type);
6835 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6836 EXPECT_REF(attributes, 1);
6838 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample2);
6839 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6840 IMFSample_Release(sample2);
6842 IMFSample_Release(sample);
6844 IMFVideoSampleAllocatorCallback_Release(allocator_cb);
6845 IMFVideoSampleAllocatorEx_Release(allocatorex);
6846 IMFAttributes_Release(attributes);
6848 /* Using device manager */
6849 if (!(device = create_d3d11_device()))
6851 skip("Failed to create a D3D11 device, skipping tests.\n");
6852 return;
6855 hr = pMFCreateDXGIDeviceManager(&token, &manager);
6856 ok(hr == S_OK, "Failed to create device manager, hr %#x.\n", hr);
6858 hr = IMFDXGIDeviceManager_ResetDevice(manager, (IUnknown *)device, token);
6859 ok(hr == S_OK, "Failed to set a device, hr %#x.\n", hr);
6861 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
6862 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6864 EXPECT_REF(manager, 1);
6865 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)manager);
6866 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6867 EXPECT_REF(manager, 2);
6869 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 0, video_type);
6870 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6872 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
6873 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6875 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
6876 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6878 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6879 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6881 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
6882 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
6883 check_interface(buffer, &IID_IMFDXGIBuffer, TRUE);
6884 check_interface(buffer, &IID_IMFGetService, FALSE);
6886 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6887 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6889 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6890 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6892 ID3D11Texture2D_GetDesc(texture, &desc);
6893 ok(desc.Width == 320, "Unexpected width %u.\n", desc.Width);
6894 ok(desc.Height == 240, "Unexpected height %u.\n", desc.Height);
6895 ok(desc.MipLevels == 1, "Unexpected miplevels %u.\n", desc.MipLevels);
6896 ok(desc.ArraySize == 1, "Unexpected array size %u.\n", desc.ArraySize);
6897 ok(desc.Format == DXGI_FORMAT_B8G8R8X8_UNORM, "Unexpected format %u.\n", desc.Format);
6898 ok(desc.SampleDesc.Count == 1, "Unexpected sample count %u.\n", desc.SampleDesc.Count);
6899 ok(desc.SampleDesc.Quality == 0, "Unexpected sample quality %u.\n", desc.SampleDesc.Quality);
6900 ok(desc.Usage == D3D11_USAGE_DEFAULT, "Unexpected usage %u.\n", desc.Usage);
6901 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6902 desc.BindFlags);
6903 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6904 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6906 ID3D11Texture2D_Release(texture);
6907 IMFDXGIBuffer_Release(dxgi_buffer);
6909 hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL);
6910 todo_wine
6911 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6913 hr = IMFMediaBuffer_Unlock(buffer);
6914 todo_wine
6915 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6917 IMFSample_Release(sample);
6919 IMFVideoSampleAllocator_Release(allocator);
6921 /* MF_SA_D3D11_USAGE */
6922 hr = MFCreateAttributes(&attributes, 1);
6923 ok(hr == S_OK, "Failed to create attributes, hr %#x.\n", hr);
6925 for (i = 0; i < ARRAY_SIZE(usage); ++i)
6927 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocatorEx, (void **)&allocatorex);
6928 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6930 hr = IMFVideoSampleAllocatorEx_SetDirectXManager(allocatorex, (IUnknown *)manager);
6931 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6933 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, usage[i]);
6934 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6936 hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(allocatorex, 0, 0, attributes, video_type);
6937 if (usage[i] == D3D11_USAGE_IMMUTABLE || usage[i] > D3D11_USAGE_STAGING)
6939 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
6940 IMFVideoSampleAllocatorEx_Release(allocatorex);
6941 continue;
6943 ok(hr == S_OK, "%u: Unexpected hr %#x.\n", usage[i], hr);
6945 hr = IMFAttributes_SetUINT32(attributes, &MF_SA_D3D11_USAGE, D3D11_USAGE_DEFAULT);
6946 ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
6948 hr = IMFVideoSampleAllocatorEx_AllocateSample(allocatorex, &sample);
6949 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6951 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
6952 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
6954 hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMFDXGIBuffer, (void **)&dxgi_buffer);
6955 ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
6957 hr = IMFDXGIBuffer_GetResource(dxgi_buffer, &IID_ID3D11Texture2D, (void **)&texture);
6958 ok(hr == S_OK, "Failed to get resource, hr %#x.\n", hr);
6960 ID3D11Texture2D_GetDesc(texture, &desc);
6961 ok(desc.Usage == usage[i], "Unexpected usage %u.\n", desc.Usage);
6962 if (usage[i] == D3D11_USAGE_DEFAULT)
6964 ok(desc.BindFlags == (D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET), "Unexpected bind flags %#x.\n",
6965 desc.BindFlags);
6966 ok(desc.CPUAccessFlags == 0, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6968 else if (usage[i] == D3D11_USAGE_DYNAMIC)
6970 ok(desc.BindFlags == D3D11_BIND_SHADER_RESOURCE, "Unexpected bind flags %#x.\n", desc.BindFlags);
6971 ok(desc.CPUAccessFlags == D3D11_CPU_ACCESS_WRITE, "Unexpected CPU access flags %#x.\n", desc.CPUAccessFlags);
6973 else if (usage[i] == D3D11_USAGE_STAGING)
6975 ok(desc.BindFlags == 0, "Unexpected bind flags %#x.\n", desc.BindFlags);
6976 ok(desc.CPUAccessFlags == (D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ), "Unexpected CPU access flags %#x.\n",
6977 desc.CPUAccessFlags);
6979 ok(desc.MiscFlags == 0, "Unexpected misc flags %#x.\n", desc.MiscFlags);
6981 ID3D11Texture2D_Release(texture);
6982 IMFDXGIBuffer_Release(dxgi_buffer);
6983 IMFMediaBuffer_Release(buffer);
6985 IMFSample_Release(sample);
6987 IMFVideoSampleAllocatorEx_Release(allocatorex);
6990 IMFAttributes_Release(attributes);
6992 IMFDXGIDeviceManager_Release(manager);
6993 ID3D11Device_Release(device);
6995 /* Use D3D9 device manager. */
6996 window = create_window();
6997 d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
6998 ok(!!d3d9, "Failed to create a D3D9 object.\n");
6999 if (!(d3d9_device = create_device(d3d9, window)))
7001 skip("Failed to create a D3D9 device, skipping tests.\n");
7002 goto done;
7005 hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager);
7006 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7008 hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token);
7009 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7011 hr = pMFCreateVideoSampleAllocatorEx(&IID_IMFVideoSampleAllocator, (void **)&allocator);
7012 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7014 hr = IMFVideoSampleAllocator_SetDirectXManager(allocator, (IUnknown *)d3d9_manager);
7015 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7017 hr = IMFVideoSampleAllocator_InitializeSampleAllocator(allocator, 1, video_type);
7018 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7020 hr = IMFVideoSampleAllocator_AllocateSample(allocator, &sample);
7021 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7023 check_interface(sample, &IID_IMFTrackedSample, TRUE);
7024 check_interface(sample, &IID_IMFDesiredSample, FALSE);
7026 hr = IMFSample_GetBufferByIndex(sample, 0, &buffer);
7027 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7029 check_interface(buffer, &IID_IMF2DBuffer, TRUE);
7030 check_interface(buffer, &IID_IMF2DBuffer2, TRUE);
7031 check_interface(buffer, &IID_IMFGetService, TRUE);
7032 check_interface(buffer, &IID_IMFDXGIBuffer, FALSE);
7034 IMFSample_Release(sample);
7035 IMFMediaBuffer_Release(buffer);
7037 IMFVideoSampleAllocator_Release(allocator);
7038 IMFMediaType_Release(media_type);
7040 done:
7041 IDirect3D9_Release(d3d9);
7042 DestroyWindow(window);
7045 static void test_MFLockSharedWorkQueue(void)
7047 DWORD taskid, queue, queue2;
7048 HRESULT hr;
7050 if (!pMFLockSharedWorkQueue)
7052 win_skip("MFLockSharedWorkQueue() is not available.\n");
7053 return;
7056 hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
7057 ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
7059 hr = pMFLockSharedWorkQueue(NULL, 0, &taskid, &queue);
7060 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
7062 hr = pMFLockSharedWorkQueue(NULL, 0, NULL, &queue);
7063 ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
7065 taskid = 0;
7066 hr = pMFLockSharedWorkQueue(L"", 0, &taskid, &queue);
7067 ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
7069 queue = 0;
7070 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue);
7071 ok(queue & MFASYNC_CALLBACK_QUEUE_PRIVATE_MASK, "Unexpected queue id.\n");
7073 queue2 = 0;
7074 hr = pMFLockSharedWorkQueue(L"", 0, NULL, &queue2);
7075 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7076 ok(queue == queue2, "Unexpected queue %#x.\n", queue2);
7078 hr = MFUnlockWorkQueue(queue2);
7079 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7081 hr = MFUnlockWorkQueue(queue);
7082 ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
7084 hr = MFShutdown();
7085 ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
7088 START_TEST(mfplat)
7090 char **argv;
7091 int argc;
7093 init_functions();
7095 argc = winetest_get_mainargs(&argv);
7096 if (argc >= 3)
7098 test_queue_com_state(argv[2]);
7099 return;
7102 CoInitialize(NULL);
7104 test_startup();
7105 test_register();
7106 test_media_type();
7107 test_MFCreateMediaEvent();
7108 test_attributes();
7109 test_sample();
7110 test_file_stream();
7111 test_MFCreateMFByteStreamOnStream();
7112 test_system_memory_buffer();
7113 test_source_resolver();
7114 test_MFCreateAsyncResult();
7115 test_allocate_queue();
7116 test_MFLockSharedWorkQueue();
7117 test_MFCopyImage();
7118 test_MFCreateCollection();
7119 test_MFHeapAlloc();
7120 test_scheduled_items();
7121 test_serial_queue();
7122 test_periodic_callback();
7123 test_event_queue();
7124 test_presentation_descriptor();
7125 test_system_time_source();
7126 test_MFInvokeCallback();
7127 test_stream_descriptor();
7128 test_MFCalculateImageSize();
7129 test_MFCompareFullToPartialMediaType();
7130 test_attributes_serialization();
7131 test_wrapped_media_type();
7132 test_MFCreateWaveFormatExFromMFMediaType();
7133 test_async_create_file();
7134 test_local_handlers();
7135 test_create_property_store();
7136 test_dxgi_device_manager();
7137 test_MFCreateTransformActivate();
7138 test_MFTRegisterLocal();
7139 test_queue_com();
7140 test_MFGetStrideForBitmapInfoHeader();
7141 test_MFCreate2DMediaBuffer();
7142 test_MFCreateMediaBufferFromMediaType();
7143 test_MFInitMediaTypeFromWaveFormatEx();
7144 test_MFCreateMFVideoFormatFromMFMediaType();
7145 test_MFCreateDXSurfaceBuffer();
7146 test_MFCreateTrackedSample();
7147 test_MFFrameRateToAverageTimePerFrame();
7148 test_MFMapDXGIFormatToDX9Format();
7149 test_dxgi_surface_buffer();
7150 test_sample_allocator();
7151 test_MFMapDX9FormatToDXGIFormat();
7153 CoUninitialize();